본문 바로가기
개발로그/알고리즘

프로그래머스 Lv.0 안전지대

by 쩜징 2023. 7. 23.

프로그래머스 Lv.0 안전지대


지뢰가 2차원 배열 board에 1로 표시되고,

board에는 지뢰가 매설 된 지역 1과 지뢰가 없는 0만 존재한다.

지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 

안전한 지역의 칸 수를 return하라.

 

board는 n*n 배열이다.

지뢰는 1로 표시되고, 지뢰가 없는 지역은 0으로 표시된다.

 

** 결론부터 말하자면 테스트에 통과하지 못했다. 

다른 분의 풀이 방법을 보고 따라해 본 것을 정리하려고 한다.

 

처음엔 지뢰가 있는 인덱스의 왼쪽위 대각선부터 오른쪽아래 대각선까지

반복문을 돌려서 카운트하고 전체 배열의 수에서 빼는 식으로 코드를 구현했는데

지뢰가 여러개 있을 때와 지뢰가 연달아 있지 않고 여러 지역에 분포되어 있는 것을 고려하면

지뢰가 있는 각 인덱스의 위험지역이 겹치면서 카운트 수가 제대로 세어지지 않는 것을 발견했다.

 

답답함을 참지 못하고 질문하기 페이지에 들어가서 테스트 통과한 코드를 보았다.

이 분의 풀이방법은 나와는 반대로 

board의 지뢰를 발견하면 위험지역을 1로 표시하는 메소드를 호출하고,

반복문이 끝나면 안전지대의 수를 세는 방식으로 구현되었다.

 

먼저, 지뢰 위치에 따른 위험지역을 표시할 새로운 배열을 생성한다.

int[][] newBoard = new int[board.length][board.length];

 

반복문을 돌며 board의 모든 원소를 조회해서 지뢰를 발견하면

위험지역을 1로 표시할 메소드를 호출한다.

for (int i=0; i<board.length; i++) {
	for (int j=0; j<board[i].length; j++) {
		if (board[i][j]==1) 
			danger(i,j,newBoard);
	}
}

 

dager메소드는 지뢰가 있는 인덱스의 위치(i,j)와 새롭게 만든 배열(newBoard)를 파라미터로 넘겨받는다.

지뢰가 있는 상,하,좌,우,대각선의 위치는 배열의 인덱스를 벗어나면 안되기 때문에

넘어서지 않는다는 조건을 걸어서 상,하,좌,우,대각선 위치에 1을 대입한다.

void danger(int i, int j, int newBoard[][]) {
    int overX = newBoard.length;
    int overY = newBoard.length;
    
    newBoard[i][j] = 1; //bumb
    if (i>0) newBoard[i-1][j] = 1; //top
    if (i<overX-1) newBoard[i+1][j] = 1; //bottom
    if (j<overY-1) newBoard[i][j+1] = 1; //right
    if (j>0) newBoard[i][j-1] = 1; //left;
    if (i>0 && j>0) newBoard[i-1][j-1]=1; //leftTopSide
    if (i<overX-1 && j>0) newBoard[i+1][j-1] = 1; //leftBottomSide
    if (i>0 && j<overY-1) newBoard[i-1][j+1] = 1; //rightTopSide
    if (i<overX-1 && j<overY-1) newBoard[i+1][j+1] = 1; //rightBottomSide
}

 

안전지역의 개수를 셀 메소드를 호출한다.

 

countSafe메소드는 danger메소드로 새롭게 만들어진 배열(newBoard)을 파라미터로 넘겨받는다.

newBoard를 조회해서 안전지역의 수를 센다. (==newBoard[i][j]의 값이 0이면 res를 +1 한다.)

answer = countSafe(newBoard);

int countSafe(int newBoard[][]) {
    int res = 0;
    for (int i=0; i<newBoard.length; i++) {
    	for (int j=0; j<newBoard[i].length; j++) {
        	if (newBoard[i][j]==0) res++;
        }
    }
    return res;
}

 

안전지역의 수를 return하면 끝!

 

<> 전체 코드 </>

class Solution {
    public int solution(int[][] board) {
        int answer = 0;
        int[][] newBoard = new int[board.length][board.length];
        for (int i=0; i<board.length; i++) {
            for (int j=0; j<board[i].length; j++) {
                if (board[i][j]==1) {
                    danger(i,j,newBoard);
                }
            }
        }
        answer = countSafe(newBoard);
        return answer;
    }
    void danger(int i, int j, int newBoard[][]) {
        int overX = newBoard.length;
        int overY = newBoard.length;
            
        newBoard[i][j] = 1; //bumb
        if(i > 0) newBoard[i-1][j] =1; //top
        if(i < overX-1) newBoard[i+1][j] =1; //bottom
        if(j < overY-1) newBoard[i][j+1] =1; //right
        if(j > 0) newBoard[i][j-1] =1; //left
        if(i > 0 && j>0) newBoard[i-1][j-1] =1; //leftTopSide
        if(i < overX-1 && j>0) newBoard[i+1][j-1] =1; //leftBottomSide
        if(i > 0 && j<overY-1) newBoard[i-1][j+1] =1; //rightTopSide
        if(i < overX-1 && j<overY-1) newBoard[i+1][j+1] =1; //rightBottomSide
    }
    int countSafe(int newBoard[][]) {
        int res = 0;
        for (int i=0; i<newBoard.length; i++) {
            for (int j=0; j<newBoard[i].length; j++) {
                if (newBoard[i][j]==0)
                    res++;
            }
        }
        return res;
    }

}

 

반응형

댓글