#include<bits/stdc++.h>
using namespace std;
int num[120],pp=0;
bool b[120];
int n,cnt = 0;
void gen(int index)
{
if (index==0) //处理完n个数字
{
for (int i = 1;i<=n;i++)
for (int j = i+1;j<=n;j++)
{
if (abs(i-j)==abs(num[i]-num[j]))
return;
//或者 这里设置一个标记判断是否可以通过也可以 但是感觉不如直接回溯上一层快
}
cnt++;
return;
}
else {
for (int i = 1;i<=n;i++)
{
if (b[i]==false)//判断那个数存不存在
{
num[index]=i;
b[i]=true;
gen(index-1);
b[i]=false;
}
}
}
}
int main (){
cin >> n;//上限
gen(n);
cout << cnt;
return 0;
}
上面是未曾优化的n皇后问题 列举所有的全排列 然后筛选 边界条件就是达到n层,同样,里面的gen的参数可以从1到n+1,也可以从1到n+1,这个不是什么大问题,下面就优化一下代码,就是在中间的时候就可以判断,如果不符合就中途中断,也是一个典型的dfs。不同点在于中间筛选,出来即合理。
#include<bits/stdc++.h>
using namespace std;
int num[120],pp=0;
bool b[120];
int n,cnt = 0;
void gen(int index)
{
if (index==n+1) //处理完n个数字
{
cnt++;
return;
}
else {
for (int i = 1;i<=n;i++)
{
if (b[i]==false)//判断那个数存不存在 不存在
{
bool flag = true;
for (int pre = 1;pre<index;pre++)
{
if (abs(index-pre)==abs(num[pre]-i))
{
flag = false;
break;
}
}
if (flag)
{
num[index]=i;
b[i]=true;
gen(index+1);
b[i]=false;
}
}
}
}
}
int main (){
cin >> n;//上限
gen(1);
cout << cnt;
return 0;
}
这就是优化后的,每次需要新加入一个数据就和之前的相比较,合理才会加入,不合理的话,跳出内层判断的循环,直接把这个值忽略,这样走到最后的,就是成立条件的。