n-皇后问题

题目 n-皇后问题

image-ef4fb107

思路分析

对于上题的改变其实就在于 每个位置都可以选择放与不放而不需要看该位置是不是棋盘 另外 现在额外要判断两个东西 就是正反对角线也不能放 对角线怎么判断是这题的关键 详细分析的话 见——n-皇后问题分析

x,y

(0,0) (0,1) (0,2) (0,3) (0,4)

(1,0) (1,1) (1,2) (1,3) (1,4)

(2,0) (2,1) (2,2) (2,3) (2,4)

(3,0) (3,1) (3,2) (3,3) (3,4)

(4,0) (4,1) (4,2) (4,3) (4,4)

x+y

(0) (1) (2) (3) (4)

(1) (2) (3) (4) (5)

(2) (3) (4) (5) (6)

(3) (4) (5) (6) (7)

(4) (5) (6) (7) (8)

每条从右上到左下的对角线 横纵坐标相加的值都是相等的

x-y+n

(5) (4) (3) (2) (1)

(6) (5) (4) (3) (2)

(7) (6) (5) (4) (3)

(8) (7) (6) (5) (4)

(9) (8) (7) (6) (5)

n-x+y

(5) (6) (7) (8) (9)

(4) (5) (6) (7) (8)

(3) (4) (5) (6) (7)

(2) (3) (4) (5) (6)

(1) (2) (3) (4) (5)

image-80aaf4f7

正对角线 x+y 反对角线: n-x+y或者x-y+n

那还是一样 先写从点入手的

再优化成从行入手的

代码实现

从点入手

#include<bits/stdc++.h>

using namespace std;

#define endl '\n'

const int N=10;

char g[N][N];

bool row[N],col[N],dg[N*2],udg[N*2];

int n;

void dfs(int x,int y,int cnt){

    if(cnt>n)   return;

    if(y==n)    y=0,x++;

    if(x==n){

        if(cnt==n){

            for(int i=0;i<n;i++)

                puts(g[i]);

            puts("");

        }

        return;

    }

    //不放

    g[x][y]='.';

    dfs(x,y+1,cnt);

    //放 满足横纵斜都没放过才行

    if(!row[x] && !col[y] && !dg[x+y] && !udg[n-x+y]){

        row[x]=col[y]=dg[x+y]=udg[n-x+y]=true;

        g[x][y]='Q';

        dfs(x,y+1,cnt+1);

        g[x][y]='.';

        row[x]=col[y]=dg[x+y]=udg[n-x+y]=false;

    }

}

int main()

{

    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

    cin>>n;

    dfs(0,0,0);

    return 0;

}

从行入手

#include<bits/stdc++.h>

using namespace std;

#define endl '\n'

const int N=10;

char g[N][N];

bool col[N],dg[N*2],udg[N*2];

int n;

void dfs(int u/*,int cnt*/){

    // if(cnt>n)   return;//与下面同理 n一定是刚好满足的 所以剪枝失效 cnt也可以不传入

    if(u==n){

        //if(cnt==n){

            for(int i=0;i<n;i++)

                puts(g[i]);

            puts("");

        //}

        return;

    }

    for(int i=0;i<n;i++){

        //不放 由于n皇后是n*n放n个 所以每行必须有一个 现在不存在不放的情况

        // g[u][i]='.';

        // dfs(u+1,cnt);

        //放 满足横纵斜都没放过才行

        if(!col[i] && !dg[u+i] && !udg[n-u+i]){

            col[i]=dg[u+i]=udg[n-u+i]=true;

            g[u][i]='Q';

            dfs(u+1/*,cnt+1*/);

            g[u][i]='.';

            col[i]=dg[u+i]=udg[n-u+i]=false;

        }

    }

}

int main()

{

    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

    cin>>n;

    for(int i=0;i<n;i++)

        for(int j=0;j<n;j++)

            g[i][j]='.';

    dfs(0/*,0*/);

    return 0;

}

精简

#include<bits/stdc++.h>

using namespace std;

#define endl '\n'

const int N=10;

char g[N][N];

bool col[N],dg[2*N],udg[2*N];

int n;

void dfs(int u){

    if(u>n-1){

        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] && !udg[n-u+i]){

            col[i]=dg[u+i]=udg[n-u+i]=true;

            g[u][i]='Q';

            dfs(u+1);

            g[u][i]='.';

            col[i]=dg[u+i]=udg[n-u+i]=false;

        }

    }

}

int main()

{

    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

    cin>>n;

    for(int i=0;i<n;i++)

        for(int j=0;j<n;j++)

            g[i][j]='.';

    dfs(0);

    return 0;

}

同类题型

视频讲解


⬅️ 烤鸡 🏠 00-刷题理模型 ➡️ n-皇后问题分析