목차

N-Queen

ps
링크acmicpc.net/…
출처BOJ
문제 번호9663
문제명N-Queen
레벨골드 5
분류

백트래킹

시간복잡도O(n!)
인풋사이즈n<=15
사용한 언어Python
제출기록15468ms
최고기록52ms
해결날짜2020/12/09

풀이

코드

코드 1 - backtracking

"""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

"""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()