[Algorithm] 체스 퀸 배치 구하기
2023. 3. 12. 21:27ㆍAlgorithm
서로를 공격할 수 없도록 퀸을 배치하는 경우의 수를 구하는 문제이다.
백트랙킹 기법을 이용하여 불가능한 경우가 나오면 깊이 탐색을 포기하고 다른 가지를 탐색한다.
int n = 4;
int cnt = 0;
bool col[7] = { false };
bool diag1[7] = { false };
bool diag2[7] = { false };
n은 체스판의 크기, cnt는 경우의 수, col은 체스판의 열, diag1, diag2는 각각 왼쪽, 오른쪽 대각선을 의미한다.
퀸은 같은 행과, 열을 모두 이동할 수 있으므로 체스판의 행과 열에는 하나의 퀸만 올 수 있다.
void search(int y) {
if (y == n) {
cnt++;
return;
}
for (int x = 0; x < n; x++) {
if (col[x] || diag1[x + y] || diag2[x - y + n - 1]) {
continue;
}
col[x] = diag1[x + y] = diag2[x - y + n - 1] = true;
search(y + 1);
col[x] = diag1[x + y] = diag2[x - y + n - 1] = false;
}
}
search 함수를 재귀적으로 호출하면서 배치의 경우의 수를 구한다.
if (y == n) {
cnt++;
return;
}
체스판의 끝 열에 도달하면 배치 경우의 수 하나를 찾은 것이므로 cnt를 하나 늘려주고 재귀호출을 종료한다.
for (int x = 0; x < n; x++) {
if (col[x] || diag1[x + y] || diag2[x - y + n - 1]) {
continue;
}
해당 위치에 배치가 불가능하다면 continue하고,
col[x] = diag1[x + y] = diag2[x - y + n - 1] = true;
search(y + 1);
col[x] = diag1[x + y] = diag2[x - y + n - 1] = false;
배치가 가능하다면 그 배치로 인해서 배치가 불가능한 구역을 표시(true)해주고
다음 행으로 옮겨가서 재귀함수를 호출한다.
재귀함수 호출 이후에는 배치를 안한 시나리오(false로 바꿔줌)도 고려해서 반복문을 진행한다.
int main() {
search(0);
cout << cnt;
return cnt;
}
'Algorithm' 카테고리의 다른 글
[알고리즘/C++] 작업 완료 최소 시간 구하기 (0) | 2023.07.18 |
---|---|
[알고리즘/C++] 부분 최대합 구하기 (0) | 2023.07.12 |
[Algorithm] 순열 구하기 (1) | 2023.03.12 |
[Algorithm] Subset(부분집합) 구하기 (0) | 2023.03.12 |
[TopCoder] InfiniteSequence2(무한 수열) (0) | 2023.03.06 |