n-皇后问题(dfs)

题目

n− 皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
n-皇后问题(dfs)_第1张图片
现在给定整数 n,请你输出所有的满足条件的棋子摆法。

输入格式

共一行,包含整数 n。

输出格式

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

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

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

注意:行末不能有多余空格。

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

数据范围

1≤n≤9

样例输入

4

样例输出

.Q…
…Q
Q…
…Q.

…Q.
Q…
…Q
.Q…

题意

即任意两个皇后不能在同一行,同一列,同一对角线,同一反对角线。

思路

dfs ,两种写法
对角线和反对角线和x,y的关系:
n-皇后问题(dfs)_第2张图片
由于反对角线存在相减,但是题目那个不能有负的,所以加个n,我试过了反对角线写成n+x-y和n+y-x都是对的

坑点

代码

#include
using namespace std;
int n;
char num[20][20];
bool col[20],dg[20],udg[20];//列,对角线,反对角线
void dfs(int u)
{
    if(u>n)//边界
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cout<<num[i][j];
            }
            cout<<endl;
        }
        cout<<endl;
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(!col[i]&&!dg[u+i]&&!udg[n+u-i])//即符合条件
        {//这里的u相当于行x,i相当于列y
            num[u][i]='Q';//放皇后
            col[i]=dg[u+i]=udg[n+u-i]=true;//标记
            dfs(u+1);//递进下一层
            col[i]=dg[u+i]=udg[n+u-i]=false;//恢复状态
            num[u][i]='.';//恢复状态
        }
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++) num[i][j]='.';//初始化
    }
    dfs(1);
    return 0;
}
//一个个枚举放不放
#include
using namespace std;
int n;
char num[20][20];
bool col[20],dg[20],udg[20],row[20];//列,对角线,反对角线,行
void dfs(int x,int y,int s)
{
   if(y==n+1) y=1,x++;//边界
   if(x==n+1)//边界
   {
       if(s==n)//放了n个,属于正确情况
       {
           for(int i=1;i<=n;i++)
           {
               for(int j=1;j<=n;j++) cout<<num[i][j];
               cout<<endl;
           }
            cout<<endl;
       }
       return;
   }
   dfs(x,y+1,s);
   
   if(!row[x]&&!col[y]&&!dg[x+y]&&!udg[n+y-x])//符合
   {
       num[x][y]='Q';//放皇后
       row[x]=col[y]=dg[x+y]=udg[n+y-x]=true;//改变状态
       dfs(x,y+1,s+1);//递进
       row[x]=col[y]=dg[x+y]=udg[n+y-x]=false;//恢复状态
       num[x][y]='.';//恢复状态
   }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++) num[i][j]='.';
    }
    dfs(1,1,0);
    return 0;
}

总结

注意
return
边界
判断状态,恢复状态

你可能感兴趣的:(龙哥的笔记,c++,c语言,dfs)