1 条题解

  • 0
    @ 2025-6-25 19:14:26

    八重循环

    #include <bits/stdc++.h>
    using namespace std;
    // pos[i] 记录第 i 列的皇后出现在哪儿
    int pos[10];
    bool check()
    {
        for (int i = 1; i <= 8; i++)
            for (int j = 1; j < i; j++)
            {
                // 检查第 i 个皇后和第 j 个皇后是否冲突
                //(pos[i], i), (pos[j], j)
                if (pos[i] == pos[j] ||
                    i == j ||
                    i + pos[i] == j + pos[j] ||
                    i - pos[i] == j - pos[j])
                    return false;
            }
        return true;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int tot = 0;
        for (pos[1] = 1; pos[1] <= 8; pos[1]++)
            for (pos[2] = 1; pos[2] <= 8; pos[2]++)
                for (pos[3] = 1; pos[3] <= 8; pos[3]++)
                    for (pos[4] = 1; pos[4] <= 8; pos[4]++)
                        for (pos[5] = 1; pos[5] <= 8; pos[5]++)
                            for (pos[6] = 1; pos[6] <= 8; pos[6]++)
                                for (pos[7] = 1; pos[7] <= 8; pos[7]++)
                                    for (pos[8] = 1; pos[8] <= 8; pos[8]++)
                                    {
                                        if (check())
                                        {
                                            tot++;
                                            cout << "No. " << tot << "\n";
                                            for (int i = 1; i <= 8; i++)
                                            {
                                                for (int j = 1; j <= 8; j++)
                                                    if (pos[j] == i)
                                                        cout << "1 ";
                                                    else
                                                        cout << "0 ";
                                                cout << "\n";
                                            }
                                        }
                                    }
        return 0;
    }
    

    基础搜索,每列随便放,最后再检查

    #include <bits/stdc++.h>
    using namespace std;
    int n = 8, tot; // n 皇后,tot 种方案
    // pos[i] 记录第 i 列的皇后出现在哪儿
    int pos[10];
    bool check()
    {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j < i; j++)
            {
                // 检查第 i 个皇后和第 j 个皇后是否冲突
                //(pos[i], i), (pos[j], j)
                if (pos[i] == pos[j] ||
                    i == j ||
                    i + pos[i] == j + pos[j] ||
                    i - pos[i] == j - pos[j])
                    return false;
            }
        return true;
    }
    // 输出当前方案
    void outPlan()
    {
        tot++;
        cout << "No. " << tot << "\n";
        for (int i = 1; i <= 8; i++)
        {
            for (int j = 1; j <= 8; j++)
                if (pos[j] == i)
                    cout << "1 ";
                else
                    cout << "0 ";
            cout << "\n";
        }
    }
    // 从第 now 层开始考虑
    void dfs(int now)
    {
        // 前 n 层考虑完了,就检查一下
        if (now > n)
        {
            if (check())
                outPlan();
            return;
        }
        // 考虑当前这一层,然后做下一层
        for (int i = 1; i <= 8; i++)
        {
            // 考虑第 now 层放在 i 的位置
            pos[now] = i;
            dfs(now + 1);
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        tot = 0;
        dfs(1); // 从第一层考虑每层选几
        return 0;
    }
    

    搜索进阶,在每列放之前先检查

    #include <bits/stdc++.h>
    using namespace std;
    int n = 8, tot; // n 皇后,tot 种方案
    // pos[i] 记录第 i 列的皇后出现在哪儿
    int pos[10];
    // 输出当前方案
    void outPlan()
    {
        tot++;
        cout << "No. " << tot << "\n";
        for (int i = 1; i <= 8; i++)
        {
            for (int j = 1; j <= 8; j++)
                if (pos[j] == i)
                    cout << "1 ";
                else
                    cout << "0 ";
            cout << "\n";
        }
    }
    // 从第 now 层开始考虑
    void dfs(int now)
    {
        // 前 n 层考虑完了,就检查一下
        if (now > n)
        {
            outPlan();
            return;
        }
        // 考虑当前这一层,然后做下一层
        for (int i = 1; i <= 8; i++)
        {
            // 考虑第 now 层放在 i 的位置
            pos[now] = i;
            bool flag = true; // 一开始认为这个位置可以
            for (int j = 1; j <= now - 1; j++)
            {
                //  考虑 (pos[now],now) 与 (pos[j],j) 如果冲突了,就不行
                if (pos[now] == pos[j] ||
                    now == j ||
                    pos[now] + now == pos[j] + j ||
                    pos[now] - now == pos[j] - j)
                {
                    flag = false;
                    break;
                }
            }
            if (flag)
                dfs(now + 1);
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        tot = 0;
        dfs(1); // 从第一层考虑每层选几
        return 0;
    }
    

    搜索最终,用额外数组标记,但要注意撤回标记

    #include <bits/stdc++.h>
    using namespace std;
    int n = 8, tot; // n 皇后,tot 种方案
    // pos[i] 记录第 i 列的皇后出现在哪儿
    int pos[10];
    // 输出当前方案
    void outPlan()
    {
        tot++;
        cout << "No. " << tot << "\n";
        for (int i = 1; i <= 8; i++)
        {
            for (int j = 1; j <= 8; j++)
                if (pos[j] == i)
                    cout << "1 ";
                else
                    cout << "0 ";
            cout << "\n";
        }
    }
    // 从第 now 层开始考虑
    bool flag1[10], flag2[20], flag3[20];
    void dfs(int now)
    {
        // 前 n 层考虑完了,就检查一下
        if (now > n)
        {
            outPlan();
            return;
        }
        // 考虑当前这一层,然后做下一层
        for (int i = 1; i <= 8; i++)
        {
            // 考虑第 now 层放在 i 的位置
            pos[now] = i;
            //  考虑 (pos[now],now) 这个情况之前没有出现过时,才继续做
            if (!flag1[pos[now]] &&
                !flag2[pos[now] + now] &&
                !flag3[pos[now] - now + 8])
            {
                // 之后的情况中,pos[now]这一行不能放了
                flag1[pos[now]] = true;
                // 之后的情况中,行列相加为 pos[now]+now 的情况不能出现了
                flag2[pos[now] + now] = true;
                // 之后的情况中,行列相减为 pos[now]-now 的情况不能出现了
                flag3[pos[now] - now + 8] = true;
                dfs(now + 1);
                // 还原为没有放在 pos[now] 的情况
                flag1[pos[now]] = false;
                flag2[pos[now] + now] = false;
                flag3[pos[now] - now + 8] = false;
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        tot = 0;
        dfs(1); // 从第一层考虑每层选几
        return 0;
    }
    

    信息

    ID
    433
    时间
    1000ms
    内存
    128MiB
    难度
    6
    标签
    (无)
    递交数
    117
    已通过
    38
    上传者