Coding Test/BOJ
# 9663. N-Queen
soyw906
2022. 7. 3. 11:49
관련 알고리즘 : 백트래킹
문제 링크 : https://www.acmicpc.net/problem/9663
9663번: N-Queen
N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.
www.acmicpc.net
문제 풀이
우선, 퀸이 서로를 공격할 수 없게 하기 위해서는 2가지 조건을 만족해야 한다.
- 퀸이 놓인 자리에서 같은 행 또는 열에 또다른 퀸이 존재해서는 안된다.
- 퀸이 놓인 자리에서 대각선 위치에 또다른 퀸이 존재해서는 안된다.
1번 조건을 토대로 우리는 n x n 의 2차원 배열을 사용할 필요 없이,
한 열당 1개의 퀸만 존재할 수 있음을 이용해 n개의 일차원 배열만을 이용하여 이 문제를 해결할 수 있다.
col[해당 열] = (해당 열에 존재하는 퀸이 어느 행에 위치하는지 - 행에 대한 index)
이런식으로 할당해주면 된다.
이후, 한 열씩 퀸을 배치해가면서 N개의 퀸의 배치를 만족할 경우 + 위의 2가지 조건을 만족할 경우
result값을 +1 해주는 백트래킹 기법을 사용한다.
조건을 만족하지 않을 때는 검색 대상에서 제외되므로 해당 문제는 백트래킹을 이용하는 것이 빠른 시간 내에 답을 도출해낼 수 있다.
해결 코드 - C++
#include <iostream>
#define MAX 15
using namespace std;
int col[MAX];
int N;
int res = 0; // 결과값
bool check(int row)
{
// 대각선에 있을 때, 기울기가 1 또는 -1 이므로 행과 열을 좌표처럼 이용, 차이가 동일할 시 대각선에 있다고 판단
for(int i = 0; i < row; i++)
{
if(col[i] == col[row] || abs(col[row] - col[i]) == row - i)
return false;
}
return true; // 조건 만족 시
}
void nQueen(int row)
{
if(row == N) // N개의 퀸 배치 완료시
res++;
else
{
for(int i = 0; i < N; i++)
{
col[row] = i; // N까지 돌며 퀸 배치
if(check(row)) // 조건 만족 시 다음 열 퀸 배치
nQueen(row+1); // 조건 불만족 시 다른 위치에 퀸 배치
}
}
}
int main() {
cin >> N;
nQueen(0);
cout << res;
}