代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[50],total;
int b[100],c[100],d[100];//b,c,d分别代表列,主对角线,副对角线,初始值为0,当有一个皇后出现时,需要将其所占的列,主,副对角线标记为1
void dfs(int i)//这里i代表的是第i个皇后
{
if(i>n)//i>n时说明已经有了一种解法
{
total++;
if(total<=3)
{
for(int j=1;j<=n;j++)
{
printf("%d ",a[j]);
}
printf("\n");
}
return;
}
for(int j=1;j<=n;j++)
{
if(!b[j]&&!c[i+j]&&!d[i-j+n])//(i,j)所占列,主,副对角线都未被标记的情况下
{
a[i] = j;
b[j] = 1;
c[i+j] = 1;
d[i-j+n] = 1;//打标记
dfs(i+1);
b[j] = 0;
c[i+j] = 0;
d[i-j+n] = 0;//回溯的时候,需要把标记去掉
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
printf("%d",total);
return 0;
}
- 需要注意的几点性质(关于这个性质可以很容易画图得到):
1.主对角线上所有点的坐标x+y相等(这里的主对角线表示的是左下到右上)
2.副对角线上所有点的坐标x-y相等(副对角线表示左上到右下)
3.代码中d[i-j+n],加n的原因是i-j会出现负数,而我们对其加任意大小的数不会改变她表示副对角线的唯一性,至于加n的原因是i-j最大的负数是1-n,所以我们只需要加n即可。
Author:
💤ISpiker
Permalink:
https://hehelv.github.io//post/ba-huang-hou
License:
MIT License