在 N×N 棋盤上放置 N 個皇後,任意兩個皇後不同行、不同列、不同對角線。八皇後共有 92 種解。
class Queen { int position; } // 該行皇后所在列
class Board {
int size;
int[][] layout; // 0=可放,>0=被攻擊次數
}
layout[i][j] 記錄第 i 行第 j 列被攻擊的次數,支持回溯時精確撤銷。
layout[row][col] == 0 表示安全;++;--,嘗試下一列。import java.util.*;
public class NQueens {
private int solutions = 0;
private final int n;
private final Board board;
private final List<Queen> queens;
public NQueens(int n) {
this.n = n;
this.board = new Board(n);
this.queens = new ArrayList<>(n);
for (int i = 0; i < n; i++) queens.add(new Queen());
}
public void solve() {
System.out.println("開始求解 " + n + " 皇後...");
placeQueen(0);
System.out.println("總共找到 " + solutions + " 個解");
}
private void placeQueen(int row) {
for (int col = 0; col < n; col++) {
if (board.layout[row][col] == 0) {
queens.get(row).position = col;
markAttack(row, col, +1); // 標記攻擊區域
if (row == n - 1) {
printSolution(++solutions);
} else {
placeQueen(row + 1);
}
markAttack(row, col, -1); // 回溯撤銷
}
}
}
private void markAttack(int row, int col, int delta) {
for (int i = row + 1; i < n; i++) {
board.layout[i][col] += delta; // 同列
if (col - (i - row) >= 0) board.layout[i][col - (i - row)] += delta; // 左下
if (col + (i - row) < n) board.layout[i][col + (i - row)] += delta; // 右下
}
}
private void printSolution(int idx) {
System.out.println("第 " + idx + " 解:");
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++) {
System.out.print(queens.get(r).position == c ? " ♛ " : " · ");
}
System.out.println();
}
System.out.println();
}
public static void main(String[] args) {
new NQueens(8).solve(); // 可改參數如 4、10
}
}
class Queen { int position; }
class Board {
final int size;
final int[][] layout;
Board(int n) { size = n; layout = new int[n][n]; }
}
int 位掩碼表示列、主對角、副對角佔用,O(1) 判斷安全,極大提速;O(N!) 最壞,實際遠小得益於剪枝;O(N²) 棋盤 + O(N) 遞歸棧;~10ms 完成,13 皇后 ~1s,14 皇后 ~10s(普通回溯)。