递归问题-全排列问题和八皇后问题
-
不使用库函数实现全排列
#include <cstdio> using namespace std; const int maxn = 11; int n,p[maxn],hashTable[maxn] = {false}; void generateP(int index){ if(index == n+1){ for(int i = 1 ; i <= n ; i++){ printf("%d",p[i]); } printf("\n"); return ; } for(int x = 1 ; x <= n ; x++){ if(hashTable[x] == false){ p[index] = x; hashTable[x] = true; generateP(index+1); hashTable[x] = false; } } } int main(){ n = 3; generateP(1); return 0; }
-
八皇后问题
- 在全排列的代码基础上进行求解的暴力解法。(此时保证了每行,每列都不相同)
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 11; int n,cnt = 0,p[maxn],hashTable[maxn] = {false}; void generateP(int index){ if(index == n+1){ bool flag = true; for(int i = 1 ; i <= n ; i++){ for(int j = i+1 ; j <= n ; j++){ if(abs(i-j) == abs(p[i]-p[j])){ // 是否在同一条对角线上 flag = false; } } } if(flag == true) cnt++; return; } for(int x = 1 ; x <= n ; x++){ if(hashTable[x] == false){ p[index] = x; hashTable[x] = true; generateP(index+1); hashTable[x] = false; } } } int main(){ n = 8; generateP(1); printf("%d",cnt); return 0; }
- 一般来说,如果在到达递归边界前的某层,由于一些事实导致已经不需要往任何一个子问题递归,就可以直接返回上一层。一般把这种做法称为回溯法
void generateP(int index) { if (index == n + 1) { cnt++; return; // 能够到达这里一定是合法的 } for (int x = 1; x <= n; x++) { if (hashTable[x] == false) { bool flag = true; for (int pre = 1; pre < index; pre++) { // 第index列的皇后的行号为x,第pre列皇后的行号为P[pre] if (abs(index - pre) == abs(x - p[pre])) { flag = false; // 与之前的皇后在一条对角线上 break; } } if (flag) { p[index] = x; hashTable[x] = true; generateP(index+1); hashTable[x] = false; } } } }