3、全排列实现八皇后回溯法优化
朴素算法——暴力法
通过枚举所有情况,然后判断每一种情况是否合法的做法是非常朴素的;因此,我们把这种不使用优化,直接用朴素算法来解决问题的做法叫做暴力法。
回溯法
经过思考可以发现,当已经放置了一部分皇后时(程序执行到一定时),可能剩余的皇后无论如何放置都无法满足结果,此时就没必要往下递归了,直接返回上一层即可,这样就可以为程序减少很多计算量。
在这种情况下,递归函数将不再递归调用,而是返回上一层调用,这种现象称为回溯。
下面是使用回溯的写法实现八皇后:
#include<iostream>
#include<stdlib.h>
using namespace std;
const int maxn = 11;
int n, p[maxn], hashTable[maxn] = { false };
void generateP(int index,int &count) {
if (index == n + 1) {//递归边界
for (int i = 1;i <= n;i++) {
cout << p[i];
}
cout <<endl;
count++;
return;
}
//枚举1~n,预将元素x存入p[index]中
for (int x = 1;x <= n;x++) {
if(hashTable[x]==false){//第x行还没有皇后
bool flag = true;//flag为true时表示当前皇后与之前皇后没有冲突
for (int pre = 1;pre < index;pre++) {//遍历之前皇后
if (abs(index - pre) == abs(x - p[pre])) {//判断是否在一条直线上
flag = false;//与之前皇后在一条直线上
break;//不合法皇后,跳出循环判断下一位置
}
}
if (flag) {
p[index] = x;
hashTable[x] = true;
generateP(index+1,count);
hashTable[x] = false;
}
}
}
}
int main() {
cin >> n;
int count=0;
generateP(1,count);
cout <<count<< endl;
return 0;
}
运行结果:
4—皇后
8—皇后
共92组解。