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 |