N皇后问题是一个dfs问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击),问有多少种摆法。
判断优化
对于n皇问题,回溯法我们很容易能够想到,但是这样的代码提交到oj上时间复杂度肯定是无法通过的,那么我们这里就介绍一种优化,判断优化。
如图,行为x,列为y;
对于同一根蓝色线上的矩阵元素,其行列相加(i+j)的值相同,对于同一根红色线上的矩阵元素,其行-列(x-y)值相同,但是由于是减法所以会出现负数,为了避免这个问题我们可以选择用N+i-j来表示红色线。
接下来,用bool数组来标记所有的对角线是否被某一皇后占据,再用一个数组来表示第y列是否有元素。
我的代码如下:
#include<iostream>
using namespace std;
bool lie[15],lf[30],ri[30];
int vis[15],n,i,sum;//第i个皇后(第i行),vis的值等于第几列
bool check(int x,int y){//x行,y列
return lie[y]!=1&&lf[x+y]!=1&&ri[n+x-y]!=1?true:false;
}
void dfs(int x){
if(x>n){
sum++;
if(sum<=3){
for(int j=1;j<=n;j++)
cout<<vis[j]<<' ';
cout<<'\n';
}
return ; }
for(int k=1;k<=n;k++)
{
if(check(x,k))
{
vis[x]=k;
lie[k]=1;
lf[x+k]=1;
ri[n+x-k]=1;
dfs(x+1);
lie[k]=0;
lf[x+k]=0;
ri[n+x-k]=0;
}
}
return;
}
int main(){
cin>>n;
sum=0;
dfs(1);
cout<<sum<<'\n';
return 0;
}