끈기 있는 개발 공간
[Algorithm] 프로그래머스 - 블록게임 본문
https://school.programmers.co.kr/learn/courses/30/lessons/42894
접근
블록의 모양이 12가지이다. 이 중에 지울 수 있는 블록의 모양은 5개뿐이다.
또한, 그 블록을 만들기 위해 필요한 1x1 크기의 블록의 갯수는 4개이다.
이를 고려하면, 각 블록의 검사 기준 위치에서 지울 수 있는 5개의 블록을 모두 검사하면 문제를 해결할 수 있다.
검사 기준 위치는 각 블록의 최상단 최우측이다. 내가 블록을 좌측에서 우측으로 움직일 것이기 때문이다.
이 검사 기준 위치를 기반으로 검사 배열을 정의한다.
검사 배열은 검사 기준 위치에서 검사하려는 블록의 모든 1x1 블록에 접근하게 할 수 있는 변화량이다.
나는 좌측에서 우측으로 하나씩 1x1 크기의 검은 블록을 떨어트릴 것이다.
그리고 검사 기준에 부합하면 그 블록을 바로바로 지울 것이고, 다시 이 작업을 반복할 것이다. 단, 반복 하기 전 임시로 떨어트린 검은 블록은 초기화한다.
하지만, 이 때 주의해야 할 점이 하나 있다.
높이가 2인 블록은 이 방법이 유효하지만, 높이가 3인 블록은 이 방법이 유효하지 않다.
높이가 2인 블록은 좌측에서 우측으로 블록을 하나씩만 떨어트려도 (지울 수 있는 블록에 한하여 )검사 기준에 부합하는 경우가 반드시 존재하지만, 높이가 3인 블록은 같은 열에 대해 검은 블록을 하나 떨어트린 상태에서 하나 더 떨어트려야 검사 기준에 부합하기 때문이다.
이를 해결하기 위해, 좌측에서 우측으로 검은 블록을 떨어트리는 작업을 두 번 반복 후 기존 작업을 반복한다.
소스코드(Java)
import java.util.*;
class Solution {
int[][][] types = {
{ {0,-2}, {0,-1}, {1,-2}, {1,-1}, {1,0} },
{ {1,0}, {2,0}, {0,1}, {1,1}, {2,1} },
{ {1,0}, {0,-1}, {1,-1}, {2,-1}, {2,0} },
{ {0,-1}, {0,1}, {1,-1}, {1,0}, {1,1} },
{ {0,-2}, {0,-1}, {1,-2}, {1,-1}, {1,0} }
};
private int get(int[][] board, int y, int x) {
if(y >= board.length || y < 0) return -1;
if(x >= board[0].length || x < 0) return -1;
return board[y][x];
}
public int solution(int[][] board) {
int result = 0;
boolean removed;
do {
removed = false;
for(int h = 0; h < 2; h++) {
for(int j = 0; j < board[0].length; j++) {
for(int i = 0; i < board.length; i++) {
if(board[i][j] != 0) break;
if(get(board, i+1, j) != 0) board[i][j] = -2;
for(int k = 0; k < types.length; k++) {
Map<Integer, Integer> hs = new HashMap<>();
for(int l = 0; l < types[0].length; l++) {
int type = get(board, i+types[k][l][0], j+types[k][l][1]);
hs.put(type, hs.getOrDefault(type, 0)+1);
}
if(hs.containsKey(0) || hs.containsKey(-1)) continue;
if(hs.getOrDefault(-2, 0) == 1 && hs.size() == 2) {
result += 1;
removed = true;
for(int l = 0; l < types[0].length; l++) {
board[i+types[k][l][0]][j+types[k][l][1]] = 0;
}
board[i][j] = 0;
break;
}
}
}
}
}
for(int y = 0; y < board.length; y++) {
for(int x = 0; x < board[0].length; x++) {
if(board[y][x] == -2) board[y][x] = 0;
}
}
} while(removed);
return result;
}
}
'Algorithm' 카테고리의 다른 글
[Algorithm] 프로그래머스 - 동굴 탐험 (0) | 2024.08.06 |
---|---|
[Algorithm] 프로그래머스 - 지형 편집 (0) | 2024.08.06 |
[Algorithm] 프로그래머스 - 단어 퍼즐 (0) | 2024.08.01 |
[Algorithm] 프로그래머스 - 가사 검색 (0) | 2024.08.01 |
[Algorithm] 프로그래머스 - 징검다리 (0) | 2024.07.20 |