[Python] BOJ 9663 - N-Queen

728x90
반응형

https://www.acmicpc.net/problem/9663

 

9663번: N-Queen

N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.

www.acmicpc.net

# 백트래킹 문제중에 가장 대표적인 문제이다. (well-known)

 

 

1. 우선 한 행마다 하나씩 Queen을 놓음으로써 같은 행을 확인하는 작업은 하지 않아도 된다.

    N을 입력받고 col_set, diag_set1, diag_set2을 set으로 선언해준다.

    col_set은 Queen이 놓여져있는 열을 나타내고 diag_set1은 Queen이 놓여져있는

    왼쪽대각선을 나타내고 diag_set2는 Queen이 놓여져있는 오른쪽 대각선을 나타낸다.

 

2. 반복문을 돌며 (0, 0)부터 (0, N-1)까지 첫번째 행에 Queen을 놓으며 백트래킹을 실행한다.

 

3. BT함수(BackTracking)

    3-1. 만약 row나 col이 N이라면 배열범위를 벗어나므로 return해준다.

            현재 Queen을 놓으려는 col이 이미 col_set에 있다면 그 열에는 이미 Queen이 있으므로 return해준다.

            diag_set1, diag_set2도 마찬가지이다.

    

    3-2. Queen을 놓을 수 있지만, N이 cnt에 도달한 경우 N개의 Queen을 놓은 것이므로 

             answer를 1증가시키고 return해준다.

 

    3-3. col_set에 현재 열을 add해주고 diag_set1에 현재 (행-열), diag_set2에 현재 (행+열)을 넣어준다.

            반복문을 돌며 다음행에 0번째 열부터 N-1번째 열까지 BT함수를 재귀적으로 실행한다.

            BT함수를 실행한 뒤, 위에서 넣어주었던 col, (row - col), (row + col)을 remove해준다.   

 

def BT(row, col, cnt):
    global answer

    if row == N or col == N:
        return
    if col in col_set:
        return
    if (row - col) in diag_set1:
        return
    if (row + col) in diag_set2:
        return

    if cnt == N:
        answer += 1
        return

    col_set.add(col)
    diag_set1.add(row - col)
    diag_set2.add(row + col)
    for i in range(N):
        BT(row+1, i, cnt+1)
    col_set.remove(col)
    diag_set1.remove(row - col)
    diag_set2.remove(row + col)

N = int(input())  
answer = 0
col_set, diag_set1, diag_set2 = set(), set(), set()
for i in range(N):
    BT(0, i, 1)
print(answer)

(solved.ac 티어: 골드 5)

 

# 재귀, 백트래킹부분이 아직 약한데, 열심히 해보자!

728x90
반응형
TAGS.

Comments