[프로그래머스/Java] Lv.0 안전지대

febCho·2024년 5월 29일
0

코딩테스트

목록 보기
208/253
post-thumbnail

문제

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

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

- 제한사항

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

풀이

보자마자 떠올랐던 건 프로그래머스 기초 문제 중 제일 어려웠던 정수를 나선형으로 배치하기 문제였다. 그때, 방향을 바꾸어줄 변수를 따로 만들었던 게 생각이 나서 이번에도 그 방법을 이용해 보기로 했다.

다만 지난 문제보다 복잡했던 건 대각선도 생각해 주어야 하고, board의 범위를 벗어나는 경우는 제외해 주어야 한다는 것이었다. 우선 정사각형인 board의 길이를 변수 n에 저장한 뒤, 지뢰가 있는 + 위험 지역을 표시할 새로운 2차원 배열 dangerZone을 만든다.

다음으로는 방향 벡터를 만들어 주어야 하는데, 여러 번 사용할 것이기 때문에 루프를 돌며 체크할 수 있도록 변수가 아닌 배열에 저장해 주었다. 이때 x와 y는 따로 만들며 각 방향에 맞게 인덱스 값을 바꾸어줄 수 있도록 벡터 값을 넣는다. 예를 들자면 (-1, 0)은 상, (-1, 1)은 우상, (1, -1)은 좌하가 되는 것이다.

이제 for문을 돌며 주어진 board에 지뢰가 있을 때 = 값이 1일 때, dangerZone에 위험 지역까지 함께 체크해 주면 된다. if(board[i][j] == 1)인 경우, dangerZone에도 동일하게 dangerZone[i][j] = 1; 표시한다. 다음으로는 방향 벡터(dx, dy)를 이용해 위험 지역을 체크한다. 범위는 0~7까지 총 8이고, 지뢰가 있는 지역의 인덱스인 i와 j에 벡터 값들을 차례로 더해 dangerZone에 표시할 새로운 인덱스 값을 만든다.

이때 중요한 것은 앞서 말했듯 board의 범위를 벗어나지 않는지 체크해야 한다는 것이다.

  1. 체크할 x 좌표가 0 이상인지 : ni >= 0
  2. 체크할 x 좌표가 n-1 이하인지 : ni < n - 인덱스는 0부터 시작하기 때문
  3. y 좌표 위와 동일 : nj >= 0 && nj < n

위 사항을 모두 통과하면 그때, dangerZone[ni][nj] = 1; 해준다. 체크가 끝나면, dangerZone[i][j] == 0일 때마다 +1 해주어 안전 지역을 계산해 반환한다.

class Solution {
    public int solution(int[][] board) {
        int n = board.length;
        int[][] dangerZone = new int[n][n];

        int[] dx = {-1, 1, 0, 0, -1, -1, 1, 1};
        int[] dy = {0, 0, -1, 1, -1, 1, -1, 1};

        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                
                if(board[i][j] == 1){
                    dangerZone[i][j] = 1;
                    
                    for(int d=0; d<8; d++){
                        int ni = i + dx[d];
                        int nj = j + dy[d];
                        
                        if(ni >= 0 && ni < n && nj >= 0 && nj < n){
                            dangerZone[ni][nj] = 1;
                        }
                    }
                }
            }
        }

        int safeCount = 0;
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                
                if(dangerZone[i][j] == 0){
                    safeCount += 1;
                }
            }
        }

        return safeCount;
    }
}

결과

profile
Done is better than perfect.

0개의 댓글