基本的递归范式
在当前位置遍历每一种可能,如果可行的话,标记这种可能已被使用,递归求取之后的位置,这种可能之后的所有情况遍历完返回时,再将这种可能的标记去掉,使得后续遍历求取之后的位置时,能够考察(看完例子之后再返回来看看)
看两个例子:
- 全排列
#include <cstdio>
const int maxn = 15;
bool HashTable[maxn] = {0};
int n;
int p[maxn];
void genP(int id)
{
if (id == n + 1) {
for (int i = 1; i <= n; ++i) {
printf("%d", p[i]);
}
putchar('\n');
return;
}
for (int i = 1; i <= n; ++i) {
if (HashTable[i] == false) {
p[id] = i;
HashTable[i] = true;
genP(id + 1);
HashTable[i] = false;
}
}
}
int main()
{
n = 3;
genP(1);
return 0;
}
- 八皇后
#include <cstdio>
#include <cmath>
const int maxn = 100;
int n;
int count;
bool hashTable[maxn] = {0};
int p[maxn];
void genP(int id)
{
if (id == n + 1) {
++count;
return ;
}
for (int i = 1; i <= n; ++i) {
if (hashTable[i] == false) {
bool flag = true;
for (int j = 1; j < id; ++j) { //对角线剪枝
if (abs(id - j) == abs(i - p[j])) {
flag = false;
break;
}
}
if (flag) {
p[id] = i;
hashTable[i] = true;
genP(id + 1);
hashTable[i] = false;
}
}
}
}
int main()
{
n = 8;
genP(1);
printf("%d", count);
return 0;
}