n-Queens 문제 해결을 위한 백트래킹 알고리즘

문제 개요

n-Queens 문제는 n×n 크기의 체스판 위에 n개의 퀸을 배치하는 조합 최적화 문제입니다. 이때 어떤 두 퀸도 서로를 공격할 수 없어야 하며, 즉 같은 행, 열, 또는 대각선 상에 존재해서는 안 됩니다. 주어진 n에 대해 가능한 모든 배치를 출력하는 것이 목표입니다.

입력 및 출력 형식

  • 입력: 정수 n (1 ≤ n ≤ 9)
  • 출력: 각 해법은 n개의 줄로 구성되며, 각 줄은 길이 n의 문자열입니다. 빈 칸은 '.', 퀸의 위치는 'Q'로 표시합니다. 각 해법 사이에는 빈 줄이 삽입됩니다.

접근 전략

이 문제는 깊이 우선 탐색(DFS)과 백트래킹 기법을 사용해 효율적으로 해결할 수 있습니다. 핵심 아이디어는 한 행에 하나의 퀸만 배치할 수 있다는 점을 이용해, 각 행마다 적절한 열 위치를 탐색하는 것입니다. 이 과정에서 세 가지 제약 조건을 실시간으로 검사합니다:

  • 같은 열에 중복 배치되지 않도록 함 (col[])
  • 주대각선(↖↘ 방향)에 중복이 없도록 함 (dg[])
  • 부대각선(↗↙ 방향)에 중복이 없도록 함 (udg[])

대각선 인덱스는 좌표 기반으로 계산됩니다. 예를 들어, (x, y) 위치의 주대각선 인덱스는 x + y, 부대각선 인덱스는 y - x + n으로 표현하여 음수가 되지 않도록 보정합니다.

해결 코드 (백트래킹 기반)

#include <iostream>
using namespace std;

const int MAX_SIZE = 20;
int n;
char board[MAX_SIZE][MAX_SIZE];
bool columnUsed[MAX_SIZE];           // 열 사용 여부
bool mainDiagUsed[MAX_SIZE * 2];     // 주대각선 (x + y)
bool antiDiagUsed[MAX_SIZE * 2];     // 부대각선 (y - x + n)

void solve(int row) {
    if (row == n) {
        for (int i = 0; i < n; ++i) {
            cout << board[i] << endl;
        }
        cout << endl;
        return;
    }

    for (int col = 0; col < n; ++col) {
        int diag1 = row + col;
        int diag2 = col - row + n;

        if (!columnUsed[col] && !mainDiagUsed[diag1] && !antiDiagUsed[diag2]) {
            // 현재 위치에 퀸 배치
            board[row][col] = 'Q';
            columnUsed[col] = mainDiagUsed[diag1] = antiDiagUsed[diag2] = true;

            solve(row + 1);

            // 상태 복구 (백트래킹)
            columnUsed[col] = mainDiagUsed[diag1] = antiDiagUsed[diag2] = false;
            board[row][col] = '.';
        }
    }
}

int main() {
    cin >> n;

    // 초기화
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            board[i][j] = '.';
        }
    }

    solve(0);
    return 0;
}

입력 예제

4

출력 예제

.Q..
...Q
Q...
..Q.

..Q.
Q...
...Q
.Q..

알고리즘 분석

  • 시간 복잡도: O(n!) — 매 행에서 가능한 열 선택지를 줄여나가므로 완전 탐색보다 효율적입니다.
  • 공간 복잡도: O(n) — 방문 상태 배열과 재귀 스택 깊이가 최대 n입니다.

이 방법은 n이 작을 때(≤9) 매우 효과적이며, 백트래킹과 상태 추적을 통한 조기 차단(pruning)으로 불필요한 탐색을 크게 줄입니다.

태그: backtracking dfs N-Queens recursion constraint satisfaction

5월 27일 01:28에 게시됨