상태공간트리: 문제 해결 과정의 중간 상태를 각각의 노드로 나타낸 트리
N = int(input())
cnt = 0
def dfs(position_list, marks):
# 가능한 경우의 수를 찾았다면 개수를 더한 후 재귀 종료
if len(position_list) == N:
global cnt;
cnt += 1
return None
for col in range(N):
if not marks[len(position_list)][col]:
for i, row in enumerate(range(len(position_list)+1, N)):
marks[row][col] += 1 # colum을 체크하는 부분
if col+(i+1) < N: # 대각선 오른쪽을 체크하는 부분
marks[row][col+i+1] += 1
if col-(i+1) >= 0: # 대각선 왼쪽을 체크하는 부분
marks[row][col-(i+1)] += 1
position_list.append(col)
dfs(position_list, marks)
# Backtracking
position_list.pop()
for i, row in enumerate(range(len(position_list)+1, N)):
marks[row][col] -= 1
if col+(i+1) < N:
marks[row][col+i+1] -= 1
if col-(i+1) >= 0:
marks[row][col-(i+1)] -= 1
marks = [[0] * N for _ in range(N)]
dfs([], marks)
print(cnt)
marks = [[0] * N for _ in range(N)]
for col in range(N):
if not marks[len(position_list)][col]:
for i, row in enumerate(range(len(position_list)+1, N)):
marks[row][col] += 1 # colum을 체크하는 부분
if col+(i+1) < N: # 대각선 오른쪽을 체크하는 부분
marks[row][col+i+1] += 1
if col-(i+1) >= 0: # 대각선 왼쪽을 체크하는 부분
marks[row][col-(i+1)] += 1
position_list.append(col) # queen을 놓은 자리 저장
dfs(position_list, marks) # 다음 row를 살펴본다
position_list
는 queen을 놓은 자리를 나타내는 값으로, 리스트의 각 값은 column의 index를, 해당 값의 index는 row index를 나타낸다. 예로 [1,2,3] 은 [0,1], [1,2], [2,3]의 자리에 queen을 둔 것을 의미한다.if not marks[len(position_list)][col]
은 마킹이 되어 있지 않다면 queen 을 놓을 수 있는 자리라는 것을 의미한다. 해당 조건을 만족하면 queen을 두고 queen을 놓을 수 없는 자리에 마킹을 한다.for i, row in enumerate(range(len(position_list)+1, N))
position_list.append(col)
해당 자리에 queen을 두었다는것을 저장한다dfs(position_list, marks)
다음 경우의 수를 살핀다. # Backtracking
position_list.pop()
for i, row in enumerate(range(len(position_list)+1, N)):
marks[row][col] -= 1
if col+(i+1) < N:
marks[row][col+i+1] -= 1
if col-(i+1) >= 0:
marks[row][col-(i+1)] -= 1
이미지 출처