====== N-Queen ======
* 전형적인 N-queen 문제
* 최대 입력 사이즈가 15인데, 기본적인 백트래킹 구현만으로는 Python3의 시간제한을 맞추기 어렵다. 대칭을 이용한 속도 향상 테크닉이 들어가야만 통과 가능
* 그렇지만, 그냥 15까지의 모든 입력에 대한 답을 미리 구해놓고 그것을 그냥 출력해주는 꼼수로 52ms에 통과하는 것도 가능하다.
===== 풀이 =====
* [[:ps:N-queens]] 참고
===== 코드 =====
==== 코드 1 - backtracking ====
* 29076KB / 27556ms
"""Solution code for "BOJ 9663. N-Queen".
- Problem link: https://www.acmicpc.net/problem/9663
- Solution link: http://www.teferi.net/ps/problems/boj/9663
"""
def solve(N, first_col):
is_occupied_col = [i == first_col for i in range(N)]
is_occupied_up_diag = [i == first_col for i in range(N * 2 - 1)]
is_occupied_down_diag = [i == -first_col + N - 1 for i in range(N * 2 - 1)]
def solve_rec(row):
if row == N:
return 1
count = 0
for col in range(N):
u_diag = row + col
d_diag = row - col + N - 1
if (is_occupied_col[col]
or is_occupied_up_diag[u_diag]
or is_occupied_down_diag[d_diag]):
continue
is_occupied_col[col] = True
is_occupied_up_diag[u_diag] = True
is_occupied_down_diag[d_diag] = True
count += solve_rec(row + 1)
is_occupied_col[col] = False
is_occupied_up_diag[u_diag] = False
is_occupied_down_diag[d_diag] = False
return count
return solve_rec(1)
def main():
N = int(input())
answer = 0
for i in range(N // 2):
answer += solve(N, i) * 2
if N % 2:
answer += solve(N, N // 2)
print(answer)
if __name__ == '__main__':
main()
==== 코드 2 - backtracking on permutation ====
* 29076KB / 15468ms
"""Solution code for "BOJ 9663. N-Queen".
Backtracking on permutation.
- Problem link: https://www.acmicpc.net/problem/9663
- Solution link: http://www.teferi.net/ps/problems/boj/9663
"""
def solve(N, first_col):
cols = list(range(N))
cols[0], cols[first_col] = cols[first_col], cols[0]
is_occupied_up_diag = [i == first_col for i in range(N * 2 - 1)]
is_occupied_down_diag = [i == -first_col + N - 1 for i in range(N * 2 - 1)]
def solve_rec(row):
if row == N:
return 1
count = 0
for i in range(row, N):
col = cols[i]
u_diag = row + col
d_diag = row - col + N - 1
if is_occupied_up_diag[u_diag] or is_occupied_down_diag[d_diag]:
continue
cols[row], cols[i] = cols[i], cols[row]
is_occupied_up_diag[u_diag] = True
is_occupied_down_diag[d_diag] = True
count += solve_rec(row + 1)
cols[row], cols[i] = cols[i], cols[row]
is_occupied_up_diag[u_diag] = False
is_occupied_down_diag[d_diag] = False
return count
return solve_rec(1)
def main():
N = int(input())
answer = 0
for i in range(N // 2):
answer += solve(N, i) * 2
if N % 2:
answer += solve(N, N // 2)
print(answer)
if __name__ == '__main__':
main()