目录
一.汉诺塔问题:
1.什么是汉诺塔问题
背景故事:汉诺塔问题,是心理学实验研究常用的任务之一。该问题的主要材料包括三根高度相同的柱子和一些大小及颜色不同的圆盘,三根柱子分别为起始柱A、辅助柱B及目标柱C。
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的盘子全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
2.汉诺塔问题的底层逻辑
分析:对于这样一个问题,任何人都不可能直接写出移动盘子的每一步,但我们可以利用下面的方法来解决。设移动盘子数为n,为了将这n个盘子从A杆移动到C杆,可以做以下三步:
- 以C盘为中介,从A杆将1至n-1号盘移至B杆;
- 将A杆中剩下的第n号盘移至C杆;
- 以A杆为中介;从B杆将1至n-1号盘移至C杆。
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> void move(int id,char x, char y) { static int count = 1; printf("step %d:move %d %c---->%c\n",count++,id, x, y); } void hanoi(int n, char A, char B, char C) { if (n == 1) move(n,A, C); else { hanoi(n - 1, A, C, B); move(n,A, C); hanoi(n - 1, B, A, C); } } int main() { int n = 0; scanf("%d", &n); hanoi(n, 'A', 'B', 'C'); return 0; }
不需要明白汉诺塔问题递归的每一步逻辑,只需要明白其底层逻辑就可以解决问题。
关键代码为
void hanoi(int n, char A, char B, char C) { if (n == 1) move(n,A, C); else { hanoi(n - 1, A, C, B); move(n,A, C); hanoi(n - 1, B, A, C); } }
每一个递归都必须有一个递归的结束条件而
if (n == 1) move(n,A, C);
对于n-1,这个条件循环就会停下,打印每一步的操作。
对于汉诺塔的底层逻辑就是
- 将A棒的最后一个盘子不动,将其他n-1个盘子以C为中介移到B盘子上
- 再将A棒上最后一个盘子移动到C棒
- B棒上n-1个盘子再以A为中介移动到C棒上。
hanoi(n - 1, A, C, B);
move(n,A, C);
hanoi(n - 1, B, A, C);
3.汉诺塔问题总结
可能用的人不明白第三步为什们B棒就直接可以通过A移动到C棒上,其实在递归过程中移动B棒,还需进行第一步的递归将B盘子上的n-1个盘子以C为中介移动到A上,再将B棒的最后一个盘子移动到C棒上,知道进行到n=1,结束递归。
二.青蛙跳台阶
1.什么是青蛙跳台阶问题
⼀只青蛙⼀次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上⼀个n级的台阶总共有多少种跳法。
2.青蛙跳台阶的底层逻辑
其实递归就是考虑其底层逻辑
当n=1时 青蛙有一种方法
当n=2时 青蛙有两种方法一次跳两个,和跳两次一个的。
当n>2时 fun(n-1)+fun(n-2)
其实就是青蛙跳一个台阶还剩n-1个台阶就还剩fun(n-1)种方法
跳两个台阶还剩n-2个台阶就还剩fun(n-2)种方法
3.代码实现
int fun(int n)
{
if (n == 1)
return 1;
else if (n == 2)
return 2;
else if (n > 2)
return fun(n - 1) + fun(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fun(n);
printf("%d\n", ret);
return 0;
}
3.总结
其问题的关键明白每一步的底层逻辑,不需要刨根问底,只要知道为什们就可以了。
大家加油一起努力。