[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 블록 게임 (Java)
Algorithm/Programmers

[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 블록 게임 (Java)

728x90

[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 길 찾기 게임 : https://programmers.co.kr/learn/courses/30/lessons/42894

 

코딩테스트 연습 - 블록 게임 | 프로그래머스

[[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]] 2

programmers.co.kr

 

 

2019 카카오 공채의 마지막 문제 블록 게임이다.

마지막 문제라서 긴장하고 시작했는데, 생각보다 너무 쉬워서 싱거웠다.

 

블록의 종류는 총 12가지로, 아래의 그림과 같다.

문제의 조건 중에, 검은 블록을 떨어뜨려 속이 꽉 채워진 직사각형을 만들어야 하므로,

검은 블록을 떨어뜨려도 직사각형을 만들 수 없다면 유효한 블록이 아니다.

 

따라서 12가지의 블록 종류 중에 유효한 블록은 아래 5가지뿐이다.

블록의 종류가 5가지뿐이므로, 경우의 수를 나눠서 체크를 해준다. (이런 문제는 노가다가 짱이다.)

 

board의 위에서부터 탐색하며 isX 함수로 블록을 찾아준다.

블록을 찾았다면, drop 함수로 검은 블록을 떨어뜨릴 수 있는지를 체크한다.

검은 블록을 떨어뜨려 속이 꽉 채워진 직사각형이 만들어진다면, 해당 블록을 제거해준다.

여기서 한 가지 주의할 점은, 아래와 같은 케이스다.

0 0 0 0
1 2 0 0
1 2 2 2
1 1 0 0

board를 탐색할 때 좌측 상단부터 탐색하기 때문에 1번 블록은 제거되지 않은 상태로 2번 블록이 제거된다.

순서상 2번 블록이 먼저 제거되고 1번 블록이 제거되어야 하므로,

2번이 제거되면 다시 j = 0으로 바꿔서 처음부터 다시 탐색할 수 있게끔 한다.

 

2019 카카오 공채 문제도 거의 끝나간다.

6번째 문제인 매칭 점수 문제가 복잡하고 더러워 보여서 블록 게임부터 풀이하게 되었다.

7문제 중 6문제를 풀이해본 결과, 2020 카카오 공채보다 훨씬 쉽다는 느낌이 들었다.

2020 카카오 공채의 가사 검색, 외벽 점검, 블록 이동하기 문제는 3시간 이상씩 걸린 고난도 문제였는데,

2019 카카오 공채 문제는 1시간 이상 걸린 문제가 없었다.

이 정도 난이도로만 출제되면 합격할 수 있을지도...?

내일은 마지막 매칭 점수를 풀고 2018 카카오 공채로 넘어가야겠다.

 

 

총 걸린 시간 : 40분

난이도 : ★☆☆☆☆

 

코드

class Solution {
    private int n;
    private int[][] board;

    public int solution(int[][] board) {
        this.board = board;
        n = board.length;
        int answer = 0;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (board[i][j] == 0) continue;

                if (isA(i, j)) {
                    if (drop(i + 1, j + 1, board[i][j]) && drop(i + 1, j + 2, board[i][j])) {
                        remove(i, j, i + 1, j, i + 1, j + 1, i + 1, j + 2);
                        j = -1;
                        answer++;
                    }
                } else if (isB(i, j)) {
                    if (drop(i + 2, j - 1, board[i][j])) {
                        remove(i, j, i + 1, j, i + 2, j, i + 2, j - 1);
                        j = -1;
                        answer++;
                    }
                } else if (isC(i, j)) {
                    if (drop(i + 2, j + 1, board[i][j])) {
                        remove(i, j, i + 1, j, i + 2, j, i + 2, j + 1);
                        j = -1;
                        answer++;
                    }
                } else if (isD(i, j)) {
                    if (drop(i + 1, j - 1, board[i][j]) && drop(i + 1, j - 2, board[i][j])) {
                        remove(i, j, i + 1, j, i + 1, j - 1, i + 1, j - 2);
                        j = -1;
                        answer++;
                    }
                } else if (isE(i, j)) {
                    if (drop(i + 1, j - 1, board[i][j]) && drop(i + 1, j + 1, board[i][j])) {
                        remove(i, j, i + 1, j, i + 1, j - 1, i + 1, j + 1);
                        j = -1;
                        answer++;
                    }
                }
            }
        }
        return answer;
    }

    private void remove(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
        board[x1][y1] = 0;
        board[x2][y2] = 0;
        board[x3][y3] = 0;
        board[x4][y4] = 0;
    }

    private boolean drop(int x, int y, int value) {
        for (int i = 0; i < x; i++) {
            if (board[i][y] == 0) continue;
            if (board[i][y] != value) return false;
        }
        return true;
    }

    private boolean isA(int x, int y) {
        int num = board[x][y];
        if (y + 2 >= n || x + 1 >= n) return false;
        return board[x + 1][y] == num && board[x + 1][y + 1] == num && board[x + 1][y + 2] == num;
    }

    private boolean isB(int x, int y) {
        int num = board[x][y];
        if (x + 2 >= n || y - 1 < 0) return false;
        return board[x + 1][y] == num && board[x + 2][y] == num && board[x + 2][y - 1] == num;
    }

    private boolean isC(int x, int y) {
        int num = board[x][y];
        if (x + 2 >= n || y + 1 >= n) return false;
        return board[x + 1][y] == num && board[x + 2][y] == num && board[x + 2][y + 1] == num;
    }

    private boolean isD(int x, int y) {
        int num = board[x][y];
        if (x + 1 >= n || y - 2 < 0) return false;
        return board[x + 1][y] == num && board[x + 1][y - 1] == num && board[x + 1][y - 2] == num;
    }

    private boolean isE(int x, int y) {
        int num = board[x][y];
        if (x + 1 >= n || y - 1 < 0 || y + 1 >= n) return false;
        return board[x + 1][y] == num && board[x + 1][y + 1] == num && board[x + 1][y - 1] == num;
    }
}
728x90