성능 요약
- 메모리: 72.6 MB, 시간: 3.40 ms
구분
- 코딩테스트 연습 > 2018 KAKAO BLIND RECRUITMENT
Answer Code(23.11.27)
import java.util.*;
class Solution {
static boolean v[][]; // 체크 배열
public int solution(int m, int n, String[] board) {
int answer = 0;
char copy [][] = new char[m][n];
for(int i = 0; i < m; i++) {
copy[i] = board[i].toCharArray();
}
boolean flag = true;
while(flag) {
v = new boolean[m][n];
flag = false;
for(int i = 0; i < m-1; i++) {
for(int j = 0; j < n-1; j++) {
if(copy[i][j] == '#') continue; // #은 빈칸을 의미
if(check(i, j, copy)) {
v[i][j] = true;
v[i][j+1] = true;
v[i+1][j] = true;
v[i+1][j+1] = true;
flag = true;
}
}
}
answer += erase(m,n,copy);
v = new boolean[m][n];
}
return answer;
}
/* 2*2가 같은지 체크 */
public static boolean check(int x, int y, char[][] board) {
char ch = board[x][y];
if(ch == board[x][y+1] && ch ==board[x+1][y] && ch == board[x+1][y+1]) {
return true;
}
return false;
}
public static int erase(int m, int n, char [][] board) {
int cnt = 0;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(v[i][j]) {
board[i][j] = '.';
}
}
}
/* 큐를 이용해 세로로 제거 작업 진행 */
for(int i = 0; i < n; i++) {
Queue<Character> q = new LinkedList<>();
for(int j = m-1; j >=0; j--) {
if(board[j][i] == '.') {
cnt++; // 지우는 블록 카운트
} else {
q.add(board[j][i]);
}
}
int idx = m-1;
// 삭제한 블록 위의 블록들 내리기
while(!q.isEmpty()) {
board[idx--][i] = q.poll();
}
// 빈칸 채우기
for(int j = idx; j >=0; j--) {
board[j][i] = '#';
}
}
return cnt;
}
}
문제풀이
시뮬레이션 유형
으로 특정 규칙에 따라 블록이 지워지고 이동하는 과정을 반복하며 최종적으로 몇 개의 블록이 지워지는지를 구하는 것이 목표다.
-
문제에서는 다음과 같은 매개변수가 주어지고, 2가지를 기준으로 코드를 작성하면 된다.
-
판의 높이 = m
-
폭 = n
-
판의 배치 정보 = board
-
-
2*2블록이 같은지 체크하는 함수
-
현재 블록을 기준으로 오른쪽, 아래, 오른쪽 아래가 같은지 체크하면 된다.
-
이때 조심할 것은 배열의 범위를 벗어나지 않도록 해야 한다.
-
만약 2*2 블록이 같다면 이를 기록할 boolean[][] 배열에 따로 표시를 한다.
-
직접적으로 board 배열을 바꾸지 않는 이유는 모든 블록을 조사한 후에 일괄적으로 처리해야 하기 때문이다.
-
-
블록을 제거하는 함수
-
큐
를 이용해 세로로 블록을 제거하는 방법을 사용했다. -
맨 아래에서부터 큐에 집어넣고, 제거해야 하는 블록이라면 개수만 세고 큐에 넣지 않는다.
-
이후에 큐에 있는 원소를들 빼내서 아래부터 차곡차곡 블록을 쌓아준다.
-
빈 블록은 ‘#’으로 표시해준다.
-