✔️ 문제 설명
프렌즈4블록
블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록".
같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다.
만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.
블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.
만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.
위 초기 배치를 문자로 표시하면 아래와 같다.

각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다
입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.
✔️ 입출력 예

- 입출력 예제 1의 경우, 첫 번째에는 A 블록 6개가 지워지고, 두 번째에는 B 블록 4개와 C 블록 4개가 지워져, 모두 14개의 블록이 지워진다.
- 입출력 예제 2는 본문 설명에 있는 그림을 옮긴 것이다. 11개와 4개의 블록이 차례로 지워지며, 모두 15개의 블록이 지워진다.
✔️ 입력 형식
- 입력으로 판의 높이 m, 폭 n과 판의 배치 정보 board가 들어온다.
- 2 ≦ n, m ≦ 30
- board는 길이 n인 문자열 m개의 배열로 주어진다. 블록을 나타내는 문자는 대문자 A에서 Z가 사용된다.
✔️ 출력 형식
입력으로 주어진 판 정보를 가지고 몇 개의 블록이 지워질지 출력하라.
✔️ 코드 구상
사진만 봐도 대충 로직은 짜기 쉬웠던거 같다..
2차원 배열 형태로 만들어서 2x2 블록을 겹치게끔 싹 다 확인하고 다른 문자로 치환해준 다음에
치환된 문자가 아닌 문자들을 아래쪽으로 재정렬하는걸 반복하면서 2x2 블록이 없을 때 정답을 반환하면 될 것 같았다.
주의할 점이라면 2x2 블록들 중 겹치는 부분이 있는 경우와 '한꺼번에' 블록들을 지워야한다는 것 그리고 문자는 A~Z라는 것이다.
✔️ 1차 코드 (실패)
- 로직은 다 정확하게 짰는데 런타임 에러......
import java.util.*;
class Solution {
public int solution(int m, int n, String[] board) {
int answer = 0;
char[][] arr = new char[m][n];
Set<String> set = new HashSet<>();
for(int i = 0; i < m; i++) {
arr[i] = board[i].toCharArray();
}
while(true) {
int count = checkBlock(arr, set, m, n);
if(count == 0) {
break;
} else {
answer += count;
dropBlock(arr, set, m, n);
}
}
return answer;
}
public int checkBlock(char[][] arr, Set<String> set, int m, int n) {
for(int i = 0; i < m - 1; i++) {
for(int j = 0; j < n - 1; j++) {
if(arr[i][j] != '*' &&
arr[i][j] == arr[i][j + 1] &&
arr[i][j] == arr[i + 1][j] &&
arr[i][j] == arr[i + 1][j + 1]) {
set.add(i + "," + j);
set.add(i + "," + (j + 1));
set.add((i + 1) + "," + j);
set.add((i + 1) + "," + (j + 1));
}
}
}
return set.size();
}
public void dropBlock(char[][] arr, Set<String> set, int m, int n) {
Iterator iter = set.iterator();
while(iter.hasNext()) {
String e = (String) iter.next();
int x = Integer.parseInt(e.substring(0, 1));
int y = Integer.parseInt(e.substring(2));
arr[x][y] = '*';
}
for(int x = 0; x < n; x++) {
for(int y = 0; y < m; y++) {
if(arr[y][x] == '*') {
for(int i = y; i > 0; i--) {
char tmp = arr[i][x];
arr[i][x] = arr[i - 1][x];
arr[i - 1][x] = tmp;
}
}
}
}
set.clear();
}
}
✔️ 2차 코드 (성공)
- index 체크도 해봤지만 다 문제 없어서 무지성 try-catch 해보니까 런타임 에러는 사라졌다...
- 테스트 케이스 4개는 실패라고 뜨길래 천천히 다시 확인해보니 dropBlock()에서 x,y 파싱하는 부분이 문제였다!
import java.util.*;
class Solution {
public int solution(int m, int n, String[] board) {
int answer = 0;
char[][] arr = new char[m][n];
Set<String> set = new HashSet<>();
for(int i = 0; i < m; i++) {
arr[i] = board[i].toCharArray();
}
try {
while(true) {
int count = checkBlock(arr, set, m, n);
if(count == 0) {
break;
} else {
answer += count;
dropBlock(arr, set, m, n);
}
}
} catch (Exception e) {}
return answer;
}
public int checkBlock(char[][] arr, Set<String> set, int m, int n) {
for(int i = 0; i < m - 1; i++) {
for(int j = 0; j < n - 1; j++) {
if(arr[i][j] != '*' &&
arr[i][j] == arr[i][j + 1] &&
arr[i][j] == arr[i + 1][j] &&
arr[i][j] == arr[i + 1][j + 1]) {
set.add(i + "," + j);
set.add(i + "," + (j + 1));
set.add((i + 1) + "," + j);
set.add((i + 1) + "," + (j + 1));
}
}
}
return set.size();
}
public void dropBlock(char[][] arr, Set<String> set, int m, int n) {
Iterator iter = set.iterator();
while(iter.hasNext()) {
String e = (String) iter.next();
String[] splitStr = e.split(",");
int x = Integer.parseInt(splitStr[0]);
int y = Integer.parseInt(splitStr[1]);
arr[x][y] = '*';
}
for(int x = 0; x < n; x++) {
for(int y = 0; y < m; y++) {
if(arr[y][x] == '*') {
for(int i = y; i > 0; i--) {
char tmp = arr[i][x];
arr[i][x] = arr[i - 1][x];
arr[i - 1][x] = tmp;
}
}
}
}
set.clear();
}
}
📄 원문
'🧠 Algorithm > [JAVA] Programmers' 카테고리의 다른 글
[49993번] 스킬트리 (0) | 2022.06.24 |
---|---|
[72412번] 순위 검색 (0) | 2022.06.23 |
[92341번] 주차 요금 계산 (0) | 2022.06.21 |
[17677번] [1차] 뉴스 클러스터링 (0) | 2022.06.20 |
[1835번] 단체사진 찍기 (0) | 2022.06.19 |