经典例子:递归求解n的阶乘
n!=12···*n,写成递归形式:n!=(n-1)!*n,即F(n)=F(n-1)*n
#include <cstdio>
int F(int n){
if(n==0) return 1; //递归达到边界时,返回1,0!=1
else return F(n-1)*n; //递归式
}
int main(){
int n;
scanf("%d",&n);
printf("%d\n",F(n));
return 0;
}
求斐波那契数列
F(0)=1,F(n)=F(n-1)+F(n-2)
数列前几项为:1,1,2,3,5,8,13,21,···
#include <cstdio>
int F(int n){
if(n==0||n==1) return 1;
else return F(n-1)+F(n-2);
}
int main(){
int n;
scanf("%d",&n);
printf("%d\n",F(n));
return 0;
}
全排列
1~3的全排列:(1,2,3)、(1,3,2)、(2,1,3)、(2,3,1)、(3,1,2)、(3,2,1)
#include <cstdio>
const int maxn = 11;
//p保存当前以x开头的全排列,hashtable标记整数x是否已经在p中
int n,P[maxn],hashTable[maxn] = {false}; //初始化hash
//当前处理排列的第index号位
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++){ //枚举1~n,for循环完整执行一次,打印出一组排列完的数
if(hashTable[x]==false){ //x不在p中,即x在本次循环未被使用
P[index]=x; //把x加入当前排列
hashTable[x]=true; //x用过后标记已使用
generateP(index+1); //开始递归排列第index数以后的数
hashTable[x] = false; //执行完递归后x还原初始状态,准备进入下一个循环
}
}
}
int main(){
n=3;
generateP(1);
return 0;
}
n皇后问题
在一个n*n的国际象棋棋盘上放置n个皇后,使得这n个皇后两两均不在同一行,同一列,同一条对角线上,求合法的方案数
每行只能放一个,每列也只能放一个,总共有n!个排列。
生成全排列,在递归边界判断是否符合n皇后条件,即遍历每两个皇后,判断他们是否在同一条对角线上(不在同一行和同一列是显然的),若不是,count+1
代码 v1:
#include <cstdio>
#include <stdlib.h>
int count = 0;
const int maxn=100;
int n,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) count++;
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\n",count);
return 0;
}
//回溯法
/*void generateP1(int index){
if(index == n+1){
count++;
return;
}
for(int x=1;x<=n;x++){
if(hashTable[x]==false){
bool 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);
hashTable[x]=false;
}
}
}
}
int main(){
n=5;
generateP1(n);
printf("%d",count);
return 0;
}
*/
代码 v2:
#include <cstdio>
#include <stdlib.h>
#include <iostream>
using namespace std;
const int N=10;
int a[N]; //a[i]表示第i行上的皇后放在a[i]列上
//假设a[3]=7,表示第3行上的皇后放在第7列
int cnt,n;
//检查皇后所在的列和两条对角线,不能再有皇后
//对角线上,找规律,(x+y)相等,(x-y)相等
bool check(int x,int y){ //第x行上能不能把皇后放在第y列上
for(int i=1;i<=x;i++){ //枚举
if(a[i]==y) return false;
if(i+a[i]==x+y) return false;
if(i-a[i]==x-y) return false;
}
return true;
}
void dfs(int row){ //第row行的皇后放于何处
//出口
if(row==n+1){
//产生了一组解
cnt++;
return;
}
for(int i=1;i<=n;i++){
if(check(row,i)){
a[row]=i;
dfs(row+1);
a[row]=0;
}
}
}
int main(){
printf("n皇后问题,请输入n=");
scanf("%d",&n);
dfs(1);
printf("产生了%d组解\n",cnt);
return 0;
}