N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다.
N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.
브루트포스 알고리즘
백트래킹
nxn의 2차원 배열이지만, 1차원 배열로도 해결 가능하다. 최대크기가 15
인 1차원 배열을 선언하고, 각 값에는 높이에 해당하는 값을 할당함으로써 퀸을 놓는것으로 본다. 예를들어, ary[0]
에 1
이 입력되었다면, (0,1)
의 위치에 퀸을 놓은 것이다. 다만 퀸이 없는 경우는 0
이므로 퀸을 놓을 때는 1
부터 세야 한다.
퀸은 각 행당 하나씩 놓으면 되므로 어느 열에 놓을지만 결정해주면 된다. 여기 dfs
함수에서 val
이 행이고 idx
는 열이다. 즉, val
이 n
과 같아질때 카운트를 하면 되고, idx
의 위치에 삽입 가능한지만 확인하고 탐색하면 된다.
삽입 가능성에 대해서는 두 가지가 만족되어야하는데, 해당 열에 퀸이 놓여있지 않을 것. 즉, ary[idx] == 0
이어야 하며, 두 번째로 대각선 위치에 퀸이 놓여져있지 않은가를 판단해야 하는데, 이것은 valid()
를 통해 해결해주었다.
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int ary[15];
int n, cnt = 0;
bool valid(int idx, int val) {
for (int i = 0; i < n; i++) {
if (ary[i] != 0)
if (max(idx - i, i - idx) == max(val - ary[i], ary[i] - val))
return false;
}
return true;
}
void dfs(int idx, int val) {
ary[idx] = val;
if (val == n) cnt++;
for (int i = 0; i < n; i++) {
if (ary[i] == 0 && valid(i, val + 1))
dfs(i, val + 1);
}
ary[idx] = 0;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
dfs(i, 1);
printf("%d", cnt);
return 0;
}