求第 n 个斐波那契数。(不考虑溢出)int fib(int n) { if (n <= 2) { return 1; } return fib(n - 1) + fib(n - 2); } int main() { int n = 0; scanf("%d", &n); printf("%d\n", fib(n)); }
- 青蛙跳台阶问题
【简介】一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
#include <stdio.h> int frog(int n) { if (n == 1) { return 1; } else if (n == 2) { return 2; } else { return frog(n - 1) + frog(n - 2); } } int main() { int n = 0; scanf("%d", &n); printf("%d\n", frog(n)); return 0; }
- 青蛙跳台阶问题的衍生变种
【简介】一只青蛙一次可以跳上1级台阶,可以跳上2级台阶,也可以跳上3级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
#include <stdio.h> int frog(int n) { if (n == 1) { return 1; } else if (n == 2) { return 2; } else if (n == 3) { return 4; } else { return frog(n - 1) + frog(n - 2) + frog(n - 3); } } int main() { int n = 0; scanf("%d", &n); printf("%d\n", frog(n)); return 0; }
【注】若把题目条件改成青蛙一次可跳m级阶梯,我们只需计算出从1级到m级的所需步数,除此之外,只需使用递归即可。
- 汉诺塔问题
【简介】汉诺塔问题,是心理学实验研究常用的任务之一。该问题的主要材料包括三根高度相同的柱子和一些大小及颜色不同的圆盘,三根柱子分别为起始柱A、辅助柱B及目标柱C。
【来源及应用】相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。 下面给出两种简单情况的动态演示:
【思考逻辑】图解,不是按照步骤来的,从左到右依次为a,b,c三个柱子。汉诺塔永远只有三步:
- 把冰箱打开:将上面(n-1)看成一个整体,移动b柱。
- 把大象装进去:将a柱底盘移到c柱
- 把冰箱门关上:将b柱上的(n-1)移到c柱
【代码实现】
#include <stdio.h> int count = 0; void move(char a, char c,int n) { printf("第%d个盘子:%c->%c\n",n, a, c);//从起始柱到目标柱 printf("%d\n",++count);//次数 } void Hanoi(char a, char b, char c, int n) { if (n == 1) { move(a, c,n); } else { Hanoi(a, c, b, n - 1);//将n-1的盘子从起始柱A通过中转柱C移动到目标柱B move(a, c, n);//将底盘从起始柱A直接移动到目标柱C Hanoi(b, a, c, n - 1);//将n-1的盘子从起始柱B通过中转柱A移动到目标柱C } } int main() { int n = 0; printf("请输入圆盘个数\n");//有 A B C三个支柱 scanf("%d", &n); //将n个盘子从初试柱A借助于中转柱B移动到目标柱C Hanoi('A', 'B', 'C', n);//A->起始柱,b->中转柱,c->目标柱 return 0; } //非递归,求的是总次数,数学方法——递推公式 /* #include <stdio.h> #include <math.h> int Hanoi(int n) { return pow(2, n) - 1; } int main() { int n = 0; scanf("%d", &n); printf("%d\n", Hanoi(n)); return 0; } */
- 汉诺塔问题的衍生变种
【规则】:注意:小圆盘始终放置在大圆盘上, 最小的两个圆盘是一样大小的
1.一次只能移动一个圆盘.
2.每个步骤都包括从一座塔中取出上部圆盘并将其放在另一座塔的顶部或空的柱子上.
3.不能将较大的圆盘放置在较小的圆盘上.
一般情况,一根柱子上有N个圆盘, 小圆盘始终放置在大圆盘上, 最小的两个圆盘是一样大小的
先考虑2个相同大小的圆盘, 共2次移动 ;
考虑3个圆盘, 共2+1+2=5次移动;
考虑4个圆盘, 共5+1+5=11次移动;
按照这个递推规律, 对于一般的, 一根柱子上有N个圆盘, 小圆盘始终放置在大圆盘上, 最小的两个圆盘是一样大小的, 那么
因此一般的通项公式是
#include <stdio.h> int Hanoi_s(int n) { if (n == 1) return 1; if (n == 2) return 2; return 2 * Hanoi_s(n - 1) + 1; } int main() { int n = 0; scanf("%d", &n); printf("%d\n", Hanoi_s(n)); return 0; }