[模板题]n-皇后问题 原创

题目来源 模板题

算法标签 dfs,剪枝

题目描述

n-皇后问题是指将 n 个皇后放在 n∗n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

1_597ec77c49-8-queens.png

现在给定整数n,请你输出所有的满足条件的棋子摆法。

输入格式

共一行,包含整数n。

输出格式

每个解决方案占n行,每行输出一个长度为n的字符串,用来表示完整的棋盘状态。

其中”.”表示某一个位置的方格状态为空,”Q”表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围

1≤n≤9

输入样例:

4

输出样例:
.Q..
...Q
Q...
..Q.

..Q.
Q...
...Q
.Q..

思路

1.从全排列的角度入手,每行逐步往下找,因为是逐层所以不用考虑行,每次只考虑列,对角线,反对角线是否占位,满足条件输出即可。

2.从棋子元素角度入手,每个棋子都有选和不选两种情况,如果满足条件则输出。

题目代码

时间复杂度 n^2
#include<iostream>

using namespace std;

int n;
const int N = 10*2;
char g[N][N];
int col[N],dg[N],udg[N];//dg[]对角线,udg[]反对角线,col列

void dfs(int u)
{
    if(u==n){for(int i=0;i<n;i++)cout<<g[i]<<endl;cout<<endl;return;}
    
    //对角线   y=-x+b b=x+y x=i y=u
    //反对角线 y=x+b  b=y-x b=y-x+n x=i y=u
    for(int i=0;i<n;i++)
        if(!col[i]&&!dg[i+u]&&!udg[u-i+n])
        {
            g[i][u]='Q';
            col[i]=dg[i+u]=udg[u-i+n]=true;
            dfs(u+1);
            col[i]=dg[i+u]=udg[u-i+n]=false;
            g[i][u]='.';
        }
}

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;
}
时间复杂度 o(2^ (n^2))

每个位置都有选和不选两种,一共有n^2个位子

#include<iostream>

using namespace std;

const int N=10*2;
char g[N][N];
int dg[N],udg[N],col[N],row[N];
int n;

void dfs(int x,int y,int s)
{
    if(x==n)y++,x=0;//一行选完,进入下一行
    if(y==n)//整个棋盘走完
    {
        if(s==n)
        {
            for(int i=0;i<n;i++)cout<<g[i]<<endl;
            cout<<endl;
        }
        return;
    }
    
    //不选
    g[x][y]='.';
    dfs(x+1,y,s);
    
    //选
    //反对角线 y=x+b b=y-x+ b=y-x+n 对角线 y=-x+b b=x+y
    if(!col[x]&&!row[y]&&!udg[y-x+n]&&!dg[x+y])//+n是因为位置不可能是负数,加个偏移量,也可以是n-u+i
        {
            g[x][y]='Q';
            col[x]=row[y]=udg[y-x+n]=dg[x+y]=true;
            dfs(x+1,y,s+1);
            col[x]=row[y]=udg[y-x+n]=dg[x+y]=false;
            g[x][y]='.';
        }
    
}
int main()
{
    cin>>n;
    
    dfs(0,0,0);
    
    return 0;
}
posted @ 2021-05-02 13:58  俺叫西西弗斯  阅读(0)  评论(0)    收藏  举报  来源