algorithm/Graph Search

백준 9663 N-queen

hw.kr 2022. 9. 2. 00:53

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

 

9663번: N-Queen

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

www.acmicpc.net

📌 해결순서 

퀸은 현재 위치에서 상하좌우, 4방향 대각선을 칸의 제한없이 이동할 수 있다.

체스판위의 모든 퀸이 서로를 공격할 수 없게 만들기 위해서는

1. 모든 퀸이 서로 같은 열, 행에 위치하면 안됨

2. 하나의 퀸에 대한 모든 4가지 대각선 방향에 퀸이 위치하면 안됨

 

만약, 모든퀸이 서로를 공격할 수 없게 만든다면 각 행에 하나의 퀸만 존재하기 때문에, 

row = [0] * n 인 1차원 배열을 생성해서 배열의 인덱스가 행, 배열의 값이 열 이렇게 생각해볼수 있다.

첫번째 행의 모든 열에 대해 백트래킹을 사용한 dfs 완탐을 하면 답을 구할수 있다.

간단한 4 X 4 체스판에 적용해보면 다음과 같다

 

우선 , row[0] = 0 으로 (0, 0)에 첫번째 퀸을 두고 탐색을 시작한다

 

row[1] , 다음 행에서는 처음행과 같은열에 있는 위치, 처음행과 대각선에 있는 위치에 대해서는 퀸을 놓을수 없으므로 방문하지 않고 조건을 만족하는 위치를 찾는다

이 경우에는 row[1] = 2 즉, (1, 2) 위치에 2번째 퀸을 위치 시킨다

 

row[2] 의 모든 열에 대해서 위치 시킬수 있는 퀸의 좌표가 없으므로 탐색을 마무리 하고 백트래킹으로 row[1] = 3 에 대해서 탐색한다.

 

row[2] = 0 에 놓을수 있으므로 row[3] 에 대해서 탐색을 하고, row[3] = 2 에 퀸을 위치시킬수 있다. 

따라서 cnt += 1을 해준다

이 경우 row 배열은 다음과 같다.

 

이제 남은 row[3] = 3 에 대해서 판단을 한 뒤,

row[2] = 1 ~ 3 에 대해서도 동일한 탐색을 진행하고, 다시 row[0] = 2 부터 모든 탐색을 진행한다.

📌 코드

pypy3 으로 제출 해야함

import sys
input = sys.stdin.readline


def keep_search(x):
    for i in range(x):
        # 대각선 비교
        # 행 - 행 == 열 - 열 이면 대각선에 위치한다
        if row[x] == row[i] or x - i == abs(row[x] - row[i]):
            return 0
    return 1


def dfs(x):
    global cnt
    if x == n:
        cnt += 1
    else:
        for i in range(n):
            # row[0] = 0
            row[x] = i
            if keep_search(x):
                dfs(x + 1)


n = int(input())
row = [0] * n
cnt = 0
dfs(0)
print(cnt)

아마 그냥 python3 을 이용해서 맞았습니다를 띄우려면 열 , 행 , 대각에 대한 visited 배열을 만들어서 백트래킹을 진행해야 할듯 싶다..

'algorithm > Graph Search' 카테고리의 다른 글

백준 2661 좋은 수열  (0) 2022.09.10
백준 1759 암호 만들기  (0) 2022.09.07
백준 1405 미친 로봇  (0) 2022.09.04
백준 1182 부분수열의 합  (0) 2022.09.03
백준 10971 외판원 순회 2  (0) 2022.09.01