코딩 테스트/백준

[백준 9663번] N-Queen

nan-noo 2023. 4. 15. 04:28
728x90

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

 

9663번: N-Queen

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

www.acmicpc.net

유명한 백트래킹 완전 탐색 문제라고 해서 풀어봤다. Python3로 풀면 시간 초과가 나서 PyPy3로 제출했다.

# 1 <= N <= 15

import sys

readline = sys.stdin.readline

N = int(readline())

row = [-1 for _ in range(N)]  # row[i] = j: i행 j열에 퀸이 있다.


def dfs(row_index, count):
    if row_index == N:
        count += 1
        return count

    for col_index in range(N):
        row[row_index] = col_index
        if is_promising_position(row_index, col_index):
            count = dfs(row_index + 1, count)
    return count


def is_promising_position(row_index, col_index):
    for i in range(row_index): # 0행부터 차례대로 배치하므로, 위쪽 테이블만 확인하면 된다.
        if col_index == row[i]: # 같은 열에 퀸이 존재할 경우
            return False
        if row_index - i == abs(col_index - row[i]): # 대각선 방향에 퀸이 존재할 경우
            return False
    return True


print(dfs(0, 0))

count를 global 변수로 만들어도 된다.

백트래킹은 탐색을 할 때, 해가 없는 경우 다시 되돌아가서 해를 찾는 기법을 말한다. 보통 dfs로 모든 경로를 탐색하며, 조건에 맞지 않아 해가 있을 가능성이 없으면 백트래킹한다. 이런 최적화 기법을 가지치기(pruning)라 한다.

사실 문제를 보면 N이 15까지니까 탐색해도 되겠구나.. 라는 생각이 들긴 하는데, 대각선 요소를 판별하는 조건을 찾기가 어려웠다. 새벽에 풀어서 그런가;;

현재 위치를 (i, j)라 했을 때, 대각선 요소는 (i - k, j - k) 또는 (i - k, j + k) 위치에 속한다. 따라서 row_index끼리의 차이와 column_index 끼리의 차이가 같다.

728x90

'코딩 테스트 > 백준' 카테고리의 다른 글

[백준 15649번] N과 M (1)  (0) 2023.04.27
[백준 1916번] 최소 비용 구하기  (0) 2023.04.15
[백준 2252번] 줄 세우기  (0) 2023.04.15
[백준 1976번] 여행 가자  (0) 2023.04.15
[백준 1717번] 집합의 표현  (0) 2023.04.14