#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cnt=0,Colum[10];//Colum[i]表示第i行的皇后放在第Colum[i]列
void search(int k,int n)
{
if(k==n){//递归边界
cnt++;
for(int i=0;i<n;i++){
printf("(%d,%d),",i,Colum[i]);//行,列的坐标
}
printf("\n");
}
else{
for(int i=0;i<n;i++){
int ok=1;
Colum[k]=i;
for(int j=0;j<k;j++){//判断第k行的皇后与第j行的皇后是否在同一列,是否在同一对角线
if(Colum[k]==Colum[j]||k-Colum[k]==j-Colum[j]||k+Colum[k]==j+Colum[j]){
ok=0;//同一主对角线上的元素的(行-列)是一个常数,同一副对角线上的元素的(行+列)是一个常数
break;
}
}
if(ok)
search(k+1,n);
}
}
}
int main()
{
search(0,8);
printf("八皇后的个数为%d\n",cnt);
return 0;
}
效率更高的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cnt=0,Colum[10];//Colum[i]表示第i行的皇后放在第Colum[i]列
int visit[3][100];//0,1,2行分别表示已经放置的皇后占据了哪些列,主对角线,副主对角线
void search(int k,int n)
{
if(k==n){//递归边界
cnt++;
for(int i=0;i<n;i++){
printf("(%d,%d),",i,Colum[i]);//行,列的坐标
}
printf("\n");
}
else{
for(int i=0;i<n;i++){
if(!visit[0][i] && !visit[1][k+i] && !visit[2][k-i+n]){
//同一主对角线上的元素的(行-列)是一个常数,
//同一副对角线上的元素的(行+列)是一个常数,所以当visit[1][k+i]为1时,表示副对角线上有皇后
//visit[2][cur-i+n],表示主对角线上有皇后
Colum[k]=i;
visit[0][i]=visit[1][k+i]=visit[2][k-i+n]=1;//标记已经放了皇后
search(k+1,n);
visit[0][i]=visit[1][k+i]=visit[2][k-i+n]=0;//又将皇后拿走
}
}
}
}
int main()
{
memset(visit,0,sizeof(visit));
search(0,8);
printf("八皇后的个数为%d\n",cnt);
return 0;
}