[블록 게임]
* 로직
- 문제에 주어진 블록을 직사각형으로 채우게 된다면 사이즈는 2*3 or 3*2 형태가 된다
- (0,0)부터 기준점을 한 칸씩 옮기면서 2*3인 경우와 3*2인 경우를 고려한다
- 해당 사이즈만큼 탐색하면서 값이 0인 곳에서는 검은 블록을 위에서부터 떨어뜨릴 수 있는지 확인한다
- 만약 중간에 다른 블록이 있다면 불가능
- 없다면 가능
- 검은 블록을 사용한 개수를 카운팅한다
- 해당 사이즈만큼 탐색하면서 만약 검은 블록의 개수를 2개 초과한 경우엔 불가능 처리를 한다
(주어진 블록들의 개수는 항상 4개이기 때문에 -> 6 - 2 = 4) - 검은 블록의 개수까지 만족한다면 해당 사이즈만큼의 값은 0으로 갱신한다
- 위 과정을 반복하며, 만약 모든 기준점들을 다 돌았을때 제거된 블록이 하나도 없다면 종료한다
//블록게임
public class Problem_BlockGame {
static int N;
public static void main(String[] args) {
int[][] board = {
{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,4,0,0,0},{0,0,0,0,0,4,4,0,0,0},{0,0,0,0,3,0,4,0,0,0},{0,0,0,2,3,0,0,0,5,5},
{1,2,2,2,3,3,0,0,0,5},{1,1,1,0,0,0,0,0,0,5}
};
int answer = solution(board);
System.out.println(answer);
}
public static int solution(int[][] board) {
int answer = 0;
N = board.length;
//0,0부터 기준점 이동하면서 -> 2*3 or 3*2로 잘라서 가능성 비교 -> 가능하다면 지우고 & cnt++
while (true){
int cnt = 0;
for(int i=0; i<N; ++i){
for(int j=0; j<N; ++j){
if(isPossible(i, j, board)){
cnt++;
}
}
}
if(cnt == 0) break;
answer += cnt;
}
return answer;
}
private static boolean isPossible(int y, int x, int[][] board) {
//2*3 사이즈로 자르는 경우
int rowSize = 2;
int colSize = 3;
if(cropBoard(rowSize, colSize, y, x, board)){
//제거하기
removeBlock(rowSize, colSize, y, x, board);
return true;
}
//3*2 사이즈로 자르는 경우
rowSize = 3;
colSize = 2;
if(cropBoard(rowSize, colSize, y, x, board)){
removeBlock(rowSize, colSize, y, x, board);
return true;
}
return false;
}
private static void removeBlock(int rowSize, int colSize, int y, int x, int[][] board) {
for(int i=0; i<rowSize; ++i){
for(int j=0; j<colSize; ++j){
board[y+i][x+j] = 0;
}
}
}
private static boolean dropBlackBlock(int y, int x, int[][] board) {
for(int i=0; i<y; ++i){
if(board[i][x] > 0) return false;
}
return true;
}
private static boolean cropBoard(int rowSize, int colSize, int y, int x, int[][] board) {
int base = 0;
int blackBlockCnt = 0;
for(int i=0; i<rowSize; ++i){
int moveY = y + i;
for(int j=0; j<colSize; ++j){
int moveX = x + j;
if(!isRanged(moveY, moveX)) return false;
if(board[moveY][moveX] == 0) {
//검은 돌을 넣을 수 있는지 판단
if(!dropBlackBlock(moveY, moveX, board)) {
return false;
}
blackBlockCnt++;
}
else if(board[moveY][moveX] > 0){
//다른 도형이 존재한다면
if(base != 0 && base != board[moveY][moveX]) return false;
base = board[moveY][moveX];
}
}
}
if(base == 0 || blackBlockCnt > 2) return false;
return true;
}
private static boolean isRanged(int y, int x) {
if(y>=0 && y<N && x>=0 && x<N) return true;
return false;
}
}
'Algorithm > Problem_프로그래머스' 카테고리의 다른 글
알고리즘(체육복, 2016년, 가운데 글자 가져오기, 같은 숫자는 싫어) (0) | 2020.04.01 |
---|---|
알고리즘(자동 완성) (0) | 2020.03.31 |
알고리즘(셔틀버스, 무지의 먹방 라이브) (0) | 2020.03.26 |
알고리즘(숫자 게임, 지형 편집) (0) | 2020.03.23 |
알고리즘(기지국 설치) (0) | 2020.03.11 |