1. 从八皇后到N皇后:问题背景与核心思想
第一次接触八皇后问题时,我被这个看似简单却暗藏玄机的问题深深吸引。想象一下,在一个标准国际象棋棋盘上摆放8个皇后,要求她们互不攻击——这意味着任何两个皇后不能在同一行、同一列或同一对角线上。这个1848年提出的问题,至今仍是算法学习的经典案例。
但真正让我着迷的是它的扩展:当棋盘大小变为N×N,皇后数量变为N时,问题会怎样变化?这就是N皇后问题的由来。从算法角度看,八皇后只是N皇后在N=8时的特例。理解这一点后,我突然意识到,掌握N皇后的通用解法,比单纯解决八皇后要有价值得多。
**深度优先搜索(DFS)**在这里展现出惊人的适应性。它的核心思想就像走迷宫:沿着一条路走到底,走不通就退回上一个岔路口。对于N皇后问题,我们可以逐行放置皇后,在每行尝试所有可能的位置,遇到冲突就回溯。这种"试探-回退"的机制,正是DFS回溯算法的精髓所在。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. DFS解决N皇后的通用框架
2.1 数据结构设计
要实现通用的N皇后解法,首先需要设计合适的数据结构。与固定大小的八皇后不同,N皇后需要动态处理棋盘尺寸。我通常会定义以下变量:
cpp复制int N; // 棋盘大小
vector<int> queens; // 记录每行皇后所在的列
vector<bool> cols; // 标记列是否被占用
vector<bool> diag1; // 主对角线(左上到右下)
vector<bool> diag2; // 副对角线(右上到左下)
这里有个关键技巧:如何高效判断对角线冲突?通过观察发现,主对角线上所有点的行-列值相同,副对角线上行+列值相同。因此:
- 主对角线数量:2N-1,索引范围
(0 - (N-1))到((N-1) - 0),所以需要偏移N-1 - 副对角线数量:2N-1,索引范围
0+0到(N-1)+(N-1)
2.2 回溯算法实现
完整的DFS回溯框架如下:
cpp复制void dfs(int row) {
if (row == N) {
// 找到一个解,处理结果
return;
}
for (int col = 0; col < N; ++col) {
