多学习。

【DFS】AcWing843.n-皇后问题

AcWing843.n-皇后问题


题解

解法一:对每一行进行遍历,因为皇后不在同一列,故每一行取不同列(列行转换同理)

#include <iostream>
#include <cstdio>

//对每一行进行遍历,由于皇后不能在同一列,故每一行的摆放列都不同
using namespace std;

const int N = 10;

bool col[N], path[N][N];
int n;

bool check(int x, int y)
{
    for(int i = x + 1, j = y + 1; i <= n && j <= n; ++i, ++j)
        if(path[i][j])
            return false;
    for(int i = x - 1, j = y - 1; i > 0 && j > 0; --i, --j)
        if(path[i][j])
            return false;
    for(int i = x - 1, j = y + 1; i > 0 && j <= n; --i, ++j)
        if(path[i][j])
            return false;
    for(int i = x + 1, j = y - 1; i <= n && j > 0; ++i, --j)
        if(path[i][j])
            return false;
    return true;
}

void dfs(int u)
{
    if(u == n + 1)
    {
        bool flag = true;
        for(int i = 1; i <= n && flag; ++i)
            for(int j = 1; j <= n && flag; ++j)
                if(path[i][j]) flag = check(i, j);
        if(flag)
        {
            for(int i = 1; i <= n; ++i)
            {
                for(int j = 1; j <= n; ++j)
                    if(path[i][j]) printf("Q");
                    else printf(".");
                puts("");
            }
            puts("");
        }
        return;
    }
    
    for(int i = 1; i <= n; ++i)
        if(!col[i])
        {
            col[i] = true;
            path[u][i] = true;
            dfs(u + 1);
            col[i] = false;
            path[u][i] = false;
        }
        
}


int main()
{
    scanf("%d",&n);
    dfs(1);
    return 0;
}

解法二:可以每次遍历时判断是否冲突

对于对角线来说,反对角线为: y = x + b, 正对角线为: y = -x + b
即我们可以用b表示对角线, 反对角线 b = y - x + n (由于会出现负数我们加上n), 正对角线 b = y + x
三皇后为例:

#include <iostream>

using namespace std;

const int N = 10;

int n;
char g[N][N];
bool col[N], dg[2 * N], undg[2 * N]; //列,对角线,反对角线上是否有皇后


void dfs(int u)
{
    if(u == n)
    {
        for(int i = 0; i < n; ++i) puts(g[i]);
        puts("");
        return ;
    }
    for(int i = 0; i < n; ++i)
        if(!col[i] && !dg[u + i] && !undg[n + u - i])
        {
            g[u][i] = 'Q';
            col[i] = dg[u + i] = undg[n + u - i] = true;
            dfs(u + 1);
            g[u][i] = '.';
            col[i] = dg[u + i] = undg[n + u - i] = false;
        }
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n; ++j)
            g[i][j] = '.';
    dfs(0);
    return 0;
}

解法三:每个点选还是不选

#include <iostream>

using namespace std;

const int N = 10;

int n;
char g[N][N];
bool row[N],col[N], dg[2 * N], undg[2 * N]; //行, 列,对角线,反对角线上是否有皇后


void dfs(int x, int y, int s)
{
    if(y == n)  x ++, y = 0;
    if(x == n)
    {
        if(s == n)
        {
            for(int i = 0; i < n; ++i) puts(g[i]);
            puts("");
        }
        return;
    }
    
    
    dfs(x, y+1, s);  //不选
    
    
    //选
    if(!row[x] && !col[y] && !dg[x + y] && !undg[y - x + n])
    {
        g[x][y] = 'Q';
        row[x] = col[y] = dg[x + y] = undg[y - x + n] = true;
        dfs(x, y + 1, s + 1);
        g[x][y] = '.';
        row[x] = col[y] = dg[x + y] = undg[y - x + n] = false;
    }
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n; ++j)
            g[i][j] = '.';
    dfs(0,0,0);
    return 0;
}

posted @   czyaaa  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示