递归基础练习题
1. 求1+2+3+……+n的值
#include <stdio.h>
int fun(int n)
{
if (n == 1) return 1;
return n + fun(n-1);
}
void main()
{
int n;
printf(“输入一个数用于求累加:”);
scanf(“%d”, &n);
printf(“1+2+3+…+n的和为:%d\n”, fun(n));
}
2. 求1*2*3*……*n的值
#include <stdio.h>
int fun(int n)
{
if (n == 1) return 1;
return n * fun(n-1);
}
void main()
{
int n;
printf(“输入一个数用于求累乘:”);
scanf(“%d”, &n);
printf(“1*2*3*…*n的积为:%d\n”, fun(n));
}
5. 小猴子第一天摘下若干桃子,当即吃掉一半,又多吃一个.第二天早上又将剩下的桃子吃一半,又多吃一个.以后每天早上吃前一天剩下的一半另一个.到第10天早上猴子想再吃时发现,只剩下一个桃子了.问第一天猴子共摘多少个桃子?
#include <stdio.h>
int fun(int day)
{
if (day == 1) return 1;
return 2*(fun(day-1) + 1);
}
void main()
{
printf(“一共有%d个桃子!!!\n”, fun(10));
}
6. 有雌雄一对兔子,假定过两个月便可繁殖雌雄各一的一对小兔子。问过n个月后共有多少对兔子?
F(N) = { IF (N == 1) RETURN 1;
IF (N == 2) RETURN 1;
RETURN F(N – 1) + F(N -2);
7. 一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
#include <stdio.h>
int fun(int pos)
{
if (pos == 1)
return 2;
return 2*(fun(pos-1) + 1);
}
void main()
{
printf(“一共有%d个鸭子!!!\n”, fun(7));
int i, n = fun(7);
for (i = 1; i <= 7; i++) {
printf(“第%d天卖出的鸭子数是:%d\n”, i, fun(7) – n);
n = n/2 – 1;
}
}
8. 著名的菲波拉契(Fibonacci)数列,其第一项为0,第二项为1,从第三项开始,其每一项都是前两项的和。编程求出该数列前N项数据。
#include <stdio.h>
int Fibonacci(int n)
{
if (n == 1)
return 0;
if (n == 2) return 1;
return Fibonacci(n – 1) + Fibonacci(n – 2);
}
void main()
{
int n;
printf(“请输入所求的n项Fibonacci数列:”);
scanf(“%d”, &n);
printf(“n项的Fibonacci数列为:%d\n”, Fibonacci(n));
}
9. 求两个数的最大公约数。
#include <stdio.h>
int gcd(int n, int r)
{
int temp = n%r;
if (temp == 0)
return r;
else {
n = r;
r = temp;
gcd(n, r);
}
}
void main()
{
int n ,r;
printf(“请输入两个数用于求最大的公约数(用逗号分隔):”);
scanf(“%d,%d”, &n, &r);
printf(“%d和%d的最大公约数为:%d\n”, n, r, gcd(n, r));
}
10. 求两个数的最小公倍数。
//求两个数的最小公倍数递归算法。
#include “stdio.h”
int lcm(int s,int m,int n)
{
if (s%n==0) return s;
else
{
return lcm(s+m,m,n);
}
}
void main()
{
int m,n;
printf(“请输入两个数用于求最小的公倍数(用逗号分隔):”);
scanf(“%d,%d”, &n, &m);
printf(“%d和%d的最小公倍数为:%d\n”, n, m, lcm(n, n, m));
}
12. 角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。
如:输入22,
输出 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
STEP=16
#include <stdio.h>
void fun(int n)
{
static int i = 0;
if (n == 1) {
i++;
printf(“%d\n”, n);
printf(“step: %d\n”, i);
return; //递归结束
}
else {
if (n%2 == 0) {
i++;
printf(“%d “, n);
n = n/2;
}
else {
i++;
printf(“%d “, n);
n = n * 3 + 1;
}
}
fun(n);
//n的值已经在上面的计算中改变了,并实现了规模的减小
//知道n为1 结束循环
//用递归实现循环
//printf(“step: %d “, i);
}
void main()
{
int n;
printf(“请输入一个数用于求角谷数:”);
scanf(“%d”, &n);
fun(n);
}
13. 将十进制转换为二进制。
#include <stdio.h>
void fun(int n)
{
int temp = n;
if (n == 1) {
printf(“%d “, n%2);
return;
}
else {
//n = n/2;
fun(n/2);
printf(“%d “, temp%2);
}
}
void main()
{
int n;
printf(“请输入一个要转换为二进制的十进制数:”);
scanf(“%d”, &n);
fun(n);
}
15. 梯有N阶,上楼可以一步上一阶,也可以一次上二阶。编一个程序,计算共有多少种不同的走法。
IF (N == 1) RETURN 1;
IF (N == 2) RETURN 2;
RETURN F(N – 1) + F(N – 2);
16. 某人写了n封信和n个信封,如果所有的信都装错了信封。求所有的信都装错信封共有多少种不同情况?
分析:
1、当N=1和2时,易得解~,假设F(N-1)和F(N-2)已经得到,重点分析下面的情况:2、当有N封信的时候,前面N-1封信可以有N-1或者 N-2封错装
3、前者,对于每种错装,可从N-1封信中任意取一封和第N封错装,故=F(N-1)*(N-1)
4、后者简单,只能是没装错的那封和第N封交换信封,没装错的那封可以是前面N-1封中的任意一个,
故= F(N-2) * (N-1)
得到如下递推公式:
基本形式:d[1]=0; d[2]=1
递归式:d[n]= (n-1)*( d[n-1] + d[n-2])