一.分治
分治是一种思想,可以用递归的方法实现,也可以用非递归的方法实现;
二.递归
自底向上:
三.题目
1.全排列:
方法一:
#include<cstdio>
using namespace std ;
int n , P[11] ;
void generateP(int index) {
if(index == n) {
for(int i = 0 ; i < n ; i ++) printf("%d",P[i]) ;
printf("\n") ;
}
else {
for(int i = 1 ; i <= n ; i ++) {
int t = 0 ;
for(int j = 0 ; j < index ; j ++) {
if(P[j] == i) {
t = 1 ;
break ;
}
}
if(t == 0) {
P[index] = i ;
generateP(index + 1) ;
}
}
}
}
int main() {
scanf("%d",&n) ;
generateP(0) ;
return 0 ;
}
方法二:
将一重循环换成散列表;
#include<cstdio>
const int maxn = 11 ;
int n , P[maxn] , hashTable[maxn] = {false} ;
void generateP(int index) {
if(index == n) {
for(int i = 0 ; i < n ; i ++) printf("%d",P[i]) ;
printf("\n") ;
}
for(int i = 1 ; i <= n ; i ++) {
if(hashTable[i] == false) {
P[index] = i ;
hashTable[i] = true ;
generateP(index + 1) ;
hashTable[i] = false ;
}
}
}
int main() {
scanf("%d",&n) ;
generateP(0) ;
return 0 ;
}
注意:
已经有全局变量n,则不能在mian里定义一个int n;
2.八妃问题
方法一:
全排列,剔除不满足条件的;如何检查是否有在同一对角线的皇后:行数差 = 列数差(行数:数组下标,列数:数组值);
#include<cstdio>
#include<cmath>
using namespace std ;
const int maxn = 100 ;
int cnt , n , P[maxn] ;
bool hashTable[maxn] = {false} ;
void generateP(int index) {
if(index == n) {
int flag = 1 ;
for(int i = 0 ; i < n ; i ++) {
for(int j = i + 1 ; j < n ; j ++) {
if(abs(i - j) == abs(P[i] - P[j])) flag = 0 ;
}
}
if(flag == 1) cnt ++ ;
}
for(int i = 0 ; i < n ; i ++) {
if(hashTable[i] == false) {
P[index] = i ;
hashTable[i] = true ;
generateP(index + 1) ;
hashTable[i] = false ;
}
}
}
int main() {
scanf("%d",&n) ;
cnt = 0 ;
generateP(0) ;
printf("%d",cnt) ;
return 0 ;
}
方法二:回溯法
思路:
选出 index 可以放置的位置;
注意:
1).遍历上层选 index 的位置时,要利用 flag 排除不可能的位置(而不是选满足条件的位置);
2).递归式后不用恢复初始化P[maxn];
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std ;
const int maxn = 100 ;
int cnt , n ;
int P[maxn] ;
void generateP(int index) {
if(index == n) cnt ++ ;
else {
for(int i = 0 ; i < n ; i ++) {
P[index] = i ;
int flag = 1 ;
for(int j = 0 ; j < index ; j ++) {
if(i == P[j] || abs(i - P[j]) == abs(index - j)) {
flag = 0 ;
break ;
}
}
if(flag == 1) generateP(index + 1) ;
}
}
}
int main() {
scanf("%d",&n) ;
cnt = 0 ;
generateP(0) ;
printf("%d",cnt) ;
return 0 ;
}
3.《算法竞赛入门经典》7-4
代码:
#include<cstdio>
#include<cstring>
using namespace std ;
const int maxn = 20 ;
int n , P[maxn] ;
int hashTable[maxn] = {0} ;
int prime(int a) {
int flag = 1 ;
for(int i = 2 ; i < a ; i ++) {
if(a % i == 0) flag = 0 ;
}
return flag ;
}
void print_ring(int index) {
if(index == n && prime(P[n - 1] + 1) == 1) {
for(int i = 0 ; i < n ; i ++) printf("%d ",P[i]) ;
printf("\n") ;
}
else {
for(int i = 2 ; i <= n ; i ++) {
if(prime(i + P[index - 1]) == 1 && hashTable[i] == 0) {
P[index] = i ;
hashTable[i] = 1 ;
print_ring(index + 1) ;
hashTable[i] = 0 ;
}
}
}
}
int main() {
scanf("%d",&n) ;
P[0] = 1 ;
print_ring(1) ;
return 0 ;
}