#include <stdio.h>
#include <math.h>
const int maxn=11;
int n,a[maxn],hashTable[maxn]={false};
int count=0;
//当前处理排列的第index号位
void generateP(int index){
if(index==n+1){//临界条件为一次排列所有的数
int i;
for(i=1;i<=n;++i){
printf("%d",a[i]);
}
printf("\n");
return;
}
for(int x=1;x<=n;++x){//每次再一个位置试一个数
if(hashTable[x]==false){//如果这个数还没有被试
a[index]=x;//把这个数放放进去
hashTable[x]=true;//表示这个数以放入
generateP(index+1);//对index+1位置进行填充,递归填充所有
hashTable[x]=false; //对x进行回收,尝试这个位置填入下一个数
}
}
}
/*
n皇后问题,暴力法 基于全排列算法
全排列保证任意两黄守不会穿线在同一行同一列
*/
void generate (int index){
//判断临界条件:一次全排列后是否 存在任意两皇后在同一对角线上
if(index=n+1){
int i,j;
bool flag=false;
for(i=1;i<=n;++i){//i,j表示行号。a[i].a[j]表示列号
for(j=i+1;j<n;j++){//基于比较算法
if(abs(i-j)==abs(a[i]-a[j]))//i-j表示两皇后的行差,a[i -a[j表示两皇后的列差
flag==true;
}
}
if(flag==false)
count++;
return;
}
//全排列递归
int x;
for(x=1;x<=n;++x){//尝试将1-n充入index
if(hashTable[x]==false){//x未使用
a[index]=x;
hashTable[x]=true;//将x充入index
generate(index+1);//递归充入index+1
hashTable[x]=false;//尝试充入下一个数之前要将此hashTable重置
}
}
}
/*
n皇后,回溯法
遇见不满足条件的结束递归可以减少时间
*/
void generateA(int index){
//临界条件 如果能到达此临界则表示成功排列一次
if(index==n+1){
count++;
return;//这个return在递归里还蛮重要
}
for(int x=1;x<=n;++x){//第x行
//尝试放入每一个数
if(hashTable[x]==false){//第x行还没有皇后
bool flag=true;//flag位true表示当前皇后不会和之前的皇后在同一对角线
for(int pre=1;pre<index;pre++){//遍历之前的皇后
if(abs(pre-index)==abs(x-a[pre])){
//第index列皇后的行号位x,第pre列皇后的行号位P[pre]
flag=false;
break;
}
}
if(flag){//如果可以把皇后放在第x行
a[index] =x;//令第index列皇后的行号位x
hashTable[x]=true;//第x行已被占用
generateA(index+1);
hashTable[x]=false;
}
}
}
}
int main(){
n=8;
generateA(1);//从a[1]开始填
printf("%d\n",count);
return 0;
}