#include <iostream>
int a[100];
int n;
void search(int cur){
if(cur==n){ //递归边界,只要走到了这里,所有皇后必然不冲突
for(int i=0;i<n;i++)
printf("hang:%d lie:%d\n",i,a[i]);
printf("\n");
}
else{
for(int i=0;i<n;i++){
int ok=1;
a[cur]=i; //尝试把第cur行的皇后放在第i列上
for(int j=0;j<cur;j++){ //检查是否与前面的皇后冲突
if((a[cur]==a[j]) || (a[cur]-cur)==(a[j]-j) || (a[cur]+cur)==(a[j]+j)){
ok=0;
break;
}
}
if(ok){
search(cur+1); //如果合法,继续递归
}
}
}
}
int main(){
scanf("%d",&n);
search(0);
return 0;
}
上面的算法还可以改进,效率可以继续提高,利用二维数组vis[2][]直接判断当前尝试的皇后所在的列和两个对角线是否已有其他皇后。由于主对角线y-x可能小于0,为了存取方便转化为自然数,故加上n。
#include <stdio.h>
int vis[3][100];
int c[100];
int n;
int tot=0;
void search(int cur){
if(cur==n){
for(int i=0;i<n;i++)
printf("hang:%d lie:%d\n",i,c[i]);
printf("\n");
tot++;
}
else{
for(int i=0;i<n;i++){
c[cur]=i; //保存方案,如果不需要方案,则可以将该数组去掉
if(!vis[0][i] && !vis[1][cur+i] && !vis[2][i-cur+n]){
//利用二维数组直接判断
vis[0][i]=vis[1][cur+i]=vis[2][i-cur+n]=1;//修改当前位置所占去的列,对角线
search(cur+1);
vis[0][i]=vis[1][cur+i]=vis[2][i-cur+n]=0;//切记,一定要改回来
}
}
}
}
int main(){
scanf("%d",&n);
search(0);
printf("%d\n",tot);
return 0;
}