深搜专题8:N皇后
描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行,每列,每条对角线(包括两条主对角线的所有对角线)上都至多有一个棋子,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是跳棋放置的一个解。请写一个程序找出所有跳棋放置的解,并把它们以上面的序列方法输出。解按字典顺序排列,请输出前3个解,最后一行是解的总个数。 输入描述 一个数字N (6<=N<=14) 表示棋盘是N x N大小的。 输出描述 前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
用例输入:
4
用例输出:
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
难点就是在如何判断对角线。
#include <bits/stdc++.h>
using namespace std;
int vis_z[30],vis_f[30],vis[30],ans[30],sum,n;
void dfs(int x,int i){
if(x==n+1){//深度达标
sum++;
if(sum<=3){//只需输出前三个解
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
cout<<endl;
}
return;
}
for(int j=1;j<=n;j++){
if(!vis_z[i-j+n]&&!vis_f[i+j]&&!vis[j]){//判断主对角线,副对角线及列
vis_z[i-j+n]=1;
vis_f[i+j]=1;
vis[j]=1;
ans[i]=j;//标记
dfs(x+1,i+1);
vis_z[i-j+n]=0;
vis_f[i+j]=0;
vis[j]=0;
ans[i]=0;//回溯
}
}
}
int main(){
cin>>n;
dfs(1,1);
cout<<sum;//在dfs外输出总的解个数
return 0;
}