思路:以列来看,每一列都有n种放法,遍历所有列的n种放法。
在遍历到第j列第i行时,若这一行已经存在元素,则可以直接剪去,若qip[i][j]所在的对角线和反对角线已经存在元素,也可以直接减去,(很nb的判断方法,利用截距,每条对角线的截距是唯一的),否则,标记这个可以放皇后的位置,再对其所在的行、对角线、反对角线做标记
若某层dfs到达终点返回调用它的函数后,还要恢复原来的样子(把做标记的地方恢复)
#include<iostream>
using namespace std;
int n;
char qip[10][10];
bool h[10],djx[20],fdjx[20];
void dfs(int u){
if(u==n+1){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<qip[i][j];
}
cout<<endl;
}
cout<<endl;
return ;
}
for(int i=1;i<=n;i++){
if(!h[i]&&!fdjx[i+u-1]&&!djx[n+u-i]){
qip[i][u]='Q';
h[i]=fdjx[i+u-1]=djx[n+u-i]=true;
dfs(u+1);
h[i]=fdjx[i+u-1]=djx[n+u-i]=false;
qip[i][u]='.';
}
}
return ;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
qip[i][j]='.';
}
}
dfs(1);
return 0;
}