[AcWing 843] n-皇后问题

image
image

DFS 按行枚举 时间复杂度 O(n!)


点击查看代码
#include<iostream>

using namespace std;
const int N = 20;
int n;
char g[N][N];
bool col[N], dg[N], udg[N];
void dfs(int u)
{
    if (u > n) {
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++)
                cout << g[i][j];
            cout << endl;
        }
        cout << endl;
        return ;
    }
    for (int i = 1; i <= n; i ++) {
        if (!col[i] && !dg[u + i] && !udg[u - i + n]) {
            g[u][i] = 'Q';
            col[i] = dg[u + i] = udg[u - i + n] = true;
            dfs(u + 1);
            col[i] = dg[u + i] = udg[u - i + n] = false;
            g[u][i] = '.';
        }
    }
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        for (int j = 1; j <= n; j ++)
            g[i][j] = '.';
    }
    dfs(1);
    return 0;
}

image

  1. g[ N ][ N ] 用来存棋盘的字符,col 用来判断这一列是否有皇后,dg 用来判断主对角线(右下倾斜的直线)是否有皇后,udg 用来判断副对角线(右上倾斜的直线)是否有皇后;
  2. 主对角线可以看作是 u = - i + b,推出 b = u + i,副对角线可以看作是 u = i + b,推出 b = u - i,由于数组 udg 的下标为正值,故加上一个偏移量 n,即 b = u - i + n;

DFS 按每个元素枚举 时间复杂度 O(2n2)


点击查看代码
#include<iostream>

using namespace std;
const int N = 20;
int n;
char g[N][N];
bool row[N], col[N], dg[N], udg[N];
void dfs(int x, int y, int s)
{
    if (y > n)  y = 1, x ++;
    if (x > n) {
        if (s == n) {
            for (int i = 1; i <= n; i ++) {
                for (int j = 1; j <= n; j ++)
                    cout << g[i][j];
                cout << endl;
            }
            cout << endl;
        }
        return ;
    }
    dfs(x, y + 1, s);
    if (!row[y] && !col[x] && !dg[y + x] && !udg[y - x + n]) {
        g[x][y] = 'Q';
        row[y] = col[x] = dg[y + x] = udg[y - x + n] = true;
        dfs(x, y + 1, s + 1);
        row[y] = col[x] = dg[y + x] = udg[y - x + n] = false;
        g[x][y] = '.';
    }
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= n; j ++)
            g[i][j] = '.';
    dfs(1, 1, 0);
    return 0;
}

image

  1. x 用来代表横坐标,y 用来代表纵坐标,s 用来代表皇后的个数;
  2. 如果 y > n,说明走到了棋盘外面,换到下一行的第一个位置,让 y = 0,x ++;
  3. 如果 x > n,说明棋盘走完了,需要结束递归(无论是否满足条件都要结束),在结束前判断 s 是否等于需要放的皇后个数 n,如果相等,则把结果输出;
  4. 枚举每个位置是否放皇后的情况:
    ① 如果不放皇后,则直接递归调用 dfs(x, y + 1, s);
    ② 如果放皇后,需要满足如下的 4 个条件:同一行,同一列,同一主对角线,同一副对角线都没有皇后;
posted @   wKingYu  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
欢迎阅读『[AcWing 843] n-皇后问题』
点击右上角即可分享
微信分享提示