在全排列的基础上进行求解,如果在到达递归边界前的某层已经不符合,就不需要深入递归,直接进入下一轮或者跳出当前的递归层,保证当到达递归边界时表示一定符合条件。
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=100;
bool vis[MAXN];
//记录皇后所在的行数
int ROW[MAXN];
int n;
int count = 0;
//使用index表示列号
void queen(int index) {
//递归边界
if(n==index) {
//到达边界表示一定满足条件
count++;
return ;
}
//递归式
for(int row=0; row<n; row++) {
//这样限制了行和列都不会冲突,所以内部只需要判断对角线的情况即可
if(!vis[row]) {
bool flag=true;
//如果和之前任何一个皇后在对角线冲突,就换成下一行
for(int pre=0; pre<index; pre++) {
//行列的距离一样即表示在同一对角线
if(abs(pre-index)==abs(ROW[pre]-row)) {
flag=false;
break;
}
}
if(flag) {
vis[row]=true;
ROW[index]=row;
queen(index+1);
vis[row]=false;
}
}
}
}
int main() {
n=8;
queen(0);
printf("%d\n",count);
//结果为92
return 0;
}