1 条题解

  • 0
    @ 2026-10-26 13:21:31

    思路与算法

    按列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

    信息

    ID
    1756
    时间
    1000ms
    内存
    64MiB
    难度
    普及−
    标签
    递交数
    1
    已通过
    1
    上传者