八皇后问题是十九世纪著名的数学家高斯于1850年提出的,并给出76组解。问题是:在8×8的棋盘上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。用计算机计算,共有92组解。可以把八皇后问题扩展到n皇后问题,即在n×n的棋盘上摆放n个皇后,使任意两个皇后都不能处于同一行、同一列或同一斜线上。
N 皇后问题的解的数量随着 N 的增加而迅速增长。以下是前几项的解的数量:
N=1:1
N=2:0
N=3:0
N=4:2
N=5:10
N=6:4
N=7:40
N=8:92
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | /**************************************************************** * 代码作者: Alex Li * 创建时间: 2023-07-27 18:51:55 * 最后修改: 2024-12-29 21:33:25 * 文件描述: N皇后问题 ****************************************************************/ #include <bits/stdc++.h> using namespace std; int N; // 棋盘大小 int counts = 0; // 解的数量,初始化为 0 /* 输出棋盘当前状态的工具函数 */ void printSolution(vector<vector<int>> &board) { for (int i = 0; i < N; i++) { // 遍历棋盘的每一行 for (int k = 0; k < N; k++) { // 遍历棋盘的每一列 cout << (board[i][k] ? "Q " : ". "); // 输出 "Q " 表示皇后,". " 表示空位 } cout << "\n"; // 换行 } } /* 检查在 board[row][column] 位置是否可以安全地放置皇后的工具函数 */ bool isSafe(vector<vector<int>> &board, int row, int column) { // 检查当前行左侧是否有皇后 for (int i = 0; i < column; i++) { if (board[row][i]) return false; // 如果左侧存在皇后,返回 false } // 检查左上方对角线是否有皇后 for (int i = row, j = column; i >= 0 && j >= 0; i--, j--) { if (board[i][j]) return false; // 如果左上方存在皇后,返回 false } // 检查左下方对角线是否有皇后 for (int i = row, j = column; j >= 0 && i < N; i++, j--) { if (board[i][j]) return false; // 如果左下方存在皇后,返回 false } return true; // 如果没有威胁,返回 true } /* 递归函数:尝试在棋盘上放置皇后的工具函数 */ void solveNQUtil(vector<vector<int>> &board, int column) { // 基本条件:如果所有皇后都已成功放置,则增加解的数量并打印棋盘 if (column >= N) { counts++; // 解的数量加一 printSolution(board); // 打印当前解 cout << '\n'; // 输出一个空行分隔解 return; // 返回,继续寻找其他解 } // 遍历当前列的所有行,尝试放置皇后 for (int i = 0; i < N; i++) { // 检查当前行是否可以安全放置皇后 if (isSafe(board, i, column)) { board[i][column] = 1; // 放置皇后 solveNQUtil(board, column + 1); // 递归放置下一列的皇后 board[i][column] = 0; // 回溯:移除当前皇后,尝试其他可能性 } } } /* 主函数 */ int main() { cout << "Enter the size of the board (N): "; cin >> N; // 输入棋盘大小 // 初始化棋盘,初始状态下所有格子均为 0(空) vector<vector<int>> board(N, vector<int>(N, 0)); // 调用递归函数尝试放置皇后 solveNQUtil(board, 0); // 根据解的数量输出结果 if (counts > 0) cout << "There are " << counts << " solution.\n"; // 如果有解,输出解的数量 else cout << "No solutions exist.\n"; // 如果没有解,输出提示 return 0; // 程序结束 } |
洛谷:P1562 P2105