본문 바로가기

코딩 테스트/프로그래머스

N-Queen

https://school.programmers.co.kr/learn/courses/30/lessons/12952

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

Level 2

 

전공 교과 과정인 알고리즘에서 자주 다루는 문제인 N-Queen, 백트래킹을 활용해 여왕 배치 경우의 수를 구해야한다.

 

개념은 간단하다 체스의 여왕을 n x n 행렬(체스판)에 그 어떤 여왕도 잡히지 않는 n 개의 여왕 배치 방법을 구하는 것이다.

(체스에서 여왕은 상하좌우 직선 상 위치 그리고 양쪽 대각선 직선 상 위치에 모두 공격이 가능하다)

 

구현 방식은 r번째 행에 c번째 열에 여왕을 배치할 경우 

다음 r+1번째 행의 c(0~n) 열에 전부 배치가능한지 확인 후 불가능하다면 

r번째 행으로 돌아와 c+1번째 열에서 다시 진행하는 방식이다.

 

예시를 보자면

 

 

1,1에 배치할 경우 2행의 1열 2열은 진행이 불가능하다. 

이럴 경우 아래와 같이 다시 1행으로 넘어와 1,2에 배치한 뒤 다시 진행한다.

 

 

이 방법을 진행하면 결국 실패하는 경우는 미리 가지치기가 가능하고

결과적으로 최종 행에 도착하는 경우에만 배치 가능한 방법으로 판단할 수 있다. 

 

나의 경우에도 위의 방식을 거의 그대로 구현했으며

1행의 0~n 열부터 DFS 탐색을 진행하여 최종 행에 도달 시 결과값을 1 증가시킴으로 정답을 반환했다. 

단, 행렬이 1 X 1 일 경우에는 바로 1을 반환할 수 있게 했다. 

 

public class Solution { //N-Queen
    static int maxLen;
    static int answer;
    public int solution(int n) {
        maxLen = n;
        answer = 0;
        int[] queenColArr = new int[n]; //여왕들의 위치를 저장할 배열
        if(n == 1) return 1; //만약 행렬이 1x1 일 경우 1 반환 (Abnormal case)
        for(int col = 0; col < maxLen; col++) { //1행 0~n열 부터 진행
            queenColArr[0] = col; //1행 여왕 위치 저장
            dfs(1, queenColArr);
        }
        return answer;
    }

    public void dfs(int row, int[] colArr) {
        for(int col = 0; col < maxLen; col++) { //현재 행에서 0~n번째 열이 사용가능하지
            if(!isAttacked(row, col, colArr)) { //다른 여왕에게 공격당하는 위치가 아닐 경우
                if(row+1 == maxLen) { //다음 행이 없을 경우 종료
                    answer++;
                    return;
                }
                colArr[row] = col; //여왕 위치 저장
                dfs(row+1, colArr); //다음 행 진행
            }
        }
    }

    public boolean isAttacked(int row, int col, int[] colArr){
        for(int preRow = 0; preRow < row; preRow++) { //이전 여왕들의 위치 탐색
            int preCol = colArr[preRow];
            if(Math.abs(preCol-col) == (row-preRow) || preCol == col) //대각선, 동일 열 위치 확인
                return true; //공격당하는 것으로 판단
        }
        return false;
    }
}

'코딩 테스트 > 프로그래머스' 카테고리의 다른 글

행렬과 연산  (0) 2023.01.09
배달  (0) 2023.01.09
가장 큰 정사각형 찾기  (0) 2023.01.06
땅따먹기  (0) 2023.01.04
게임 맵 최단거리  (1) 2023.01.04