1 条题解
-
0
思路与算法
按列0至7放皇后,每列依次尝试行0至7,用行与两种对角线占用标记判断合法。放满8列时编号加1,按棋盘从上到下逐行打印,当前位置有皇后为1,其余为0。完成一个分支后撤销标记。
正确性说明
每列恰放1个且标记排除同行和对角线攻击,所有生成方案合法。任何合法8皇后摆法都能在各列对应行选择中被枚举,且每列行选择唯一所以无重复。递增行选择决定题目样例中的按列字典序,打印时转成逐行棋盘。独立全排列枚举得到92解,且前两个完整棋盘与公开样例逐项一致。
复杂度
递归深度8,候选搜索上界O(8!),输出92×64个棋盘值。对本固定任务为常量,额外标记数组与栈O(8),全局标记零初始化O(8)。
易错点
样例顺序是按列枚举行号,不能按每行枚举列号后直接打印,二者互为转置且前几个棋盘不同。输出No. 编号格式,必须打印全部92个解,公开样例的省略号不是结果的一部分。
参考代码(C++11)
#include <bits/stdc++.h> using namespace std; int pos[8], number; bool used[8], diag1[15], diag2[15]; void dfs(int c) { if (c == 8) { cout << "No. " << ++number << '\n'; for (int r = 0; r < 8; ++r) { for (int j = 0; j < 8; ++j) cout << (pos[j] == r ? 1 : 0) << (j == 7 ? '\n' : ' '); } return; } for (int r = 0; r < 8; ++r) if (!used[r] && !diag1[c - r + 7] && !diag2[c + r]) { pos[c] = r; used[r] = diag1[c - r + 7] = diag2[c + r] = true; dfs(c + 1); used[r] = diag1[c - r + 7] = diag2[c + r] = false; } } int main() { dfs(0); }
- 1