안전지대 Lv. 0

박영준·2023년 5월 18일
0

코딩테스트

목록 보기
97/300

다시 풀어보기

문제 설명

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.

지뢰는 2차원 배열 board에 1로 표시되어 있고 board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역 0만 존재합니다.
지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return하도록 solution 함수를 완성해주세요.

class Solution {
    public int solution(int[][] board) {
        int answer = 0;
        return answer;
    }
}

제한 사항

  • board는 n * n 배열입니다.
  • 1 ≤ n ≤ 100
  • 지뢰는 1로 표시되어 있습니다.
  • board에는 지뢰가 있는 지역 1과 지뢰가 없는 지역 0만 존재합니다.

입출력 예

입출력 예 설명

  • 입출력 예 #1

    • (3, 2)에 지뢰가 있으므로 지뢰가 있는 지역과 지뢰와 인접한 위, 아래, 좌, 우, 대각선 총 8칸은 위험지역입니다. 따라서 16을 return합니다.
  • 입출력 예 #2

    • (3, 2), (3, 3)에 지뢰가 있으므로 지뢰가 있는 지역과 지뢰와 인접한 위, 아래, 좌, 우, 대각선은 위험지역입니다. 따라서 위험지역을 제외한 칸 수 13을 return합니다.
  • 입출력 예 #3

    • 모든 지역에 지뢰가 있으므로 안전지역은 없습니다. 따라서 0을 return합니다.

해결법

방법 1

class Solution {
    public int solution(int[][] board) {
        int[][] boomBoard = new int[board.length][board[0].length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                if (board[i][j] == 1) checkExplosion(i, j, boomBoard);
            }
        }

        int count = 0;
        for (int[] array : boomBoard) {
            for (int value : array) {
                if (value == 0) count++;
            }
        }
        return count;
    }

    static void checkExplosion(int x, int y, int[][] boomBoard) {
        int explosionX;
        int explosionY;
        int[] aroundX = {0, -1, -1, -1, 0, 0, 1, 1, 1};
        int[] aroundY = {0, -1, 0, 1, -1, 1, -1, 0, 1};
        for (int i = 0; i < 9; i++) {
            explosionX = x + aroundX[i];
            explosionY = y + aroundY[i];
            if (explosionX < boomBoard.length && explosionY < boomBoard.length)
                if (explosionX >= 0 && explosionY >= 0) boomBoard[explosionX][explosionY] = 1;
        }
    }
}

문제를 설명하자면 폭탄이 있으면 그 주변의 상하좌우, 대각선은 위험지역이다.
그래서 주어진 배열에 폭탄표시가 있고 폭탄이 터지는 위험지역을 제외한 지역
즉, 안전지역의 숫자를 출력하는 문제이다.

주어진 폭탄의 위치를 표기한 배열과 동일한 크기를 가진 배열을 생성하여 폭탄을 포함한 위험지역을 체크하도록 구현하였다.

checkExplosion() 함수를 살펴보면 폭탄이 있는 위치를 포함하여 상하좌우와 대각선 모두를 포함하기 위해 그 주변을 다 체크할 수 있도록 두 개의 배열을 만들었다.
그런데 폭탄이 구석에 있는 경우 배열의 범위를 벗어나는데 그 부분은 체크하지 않도록 범위를 0이상 배열의 사이즈 미만으로 설정하였다.

방법 2

class Solution {
    public int solution(int[][] board) {
        int answer = 0;
        int length = board.length;   // 길이
        int[][] temp = new int[length+2][length+2];		// 길이를 2 늘린 액자용 배열 생성 -> 이러면 단순한 조건식으로 안전영역 구할 수 있음

        // 액자에 board 이식.
        for(int i=1; i<length+1; i++){
            for(int j=1; j<length+1;j++){
                temp[i][j]=board[i-1][j-1];
            }
        }

        //위험지대 찾기
        for(int i=1; i<length+1; i++){
            for(int j=1; j<length+1;j++){
                if(temp[i][j]==1){
                    for(int a = i-1; a<=i+1; a++){
                        for(int b =j-1; b<=j+1; b++){
                            if(temp[a][b]!=1) temp[a][b]=2;
                        }
                    }
                }
            }
        }

        // 안전지대 카운트
        for(int i=1; i<length+1; i++){
            for(int j=1; j<length+1;j++){
                if(temp[i][j]==0) answer++;
                System.out.print(temp[i][j]);
            }
            System.out.println("");
        }

        return answer;
    }
}

안전지대

profile
개발자로 거듭나기!

0개의 댓글