汉诺塔
博主是大一菜鸡蛋子一枚,欢迎与我交流讨论
**首先,可以先引进一个超简单小问题:一只猴子摘了N个桃子第一天吃了一半又多吃了一个,
第二天又吃了余下的一半又多吃了一个,到第X天的时候发现还有Y个,问,N为多少(X、Y均自行设置)
本文介绍一种逆推思想:前一天的桃子=(后一天的桃子+1)×2
int Peach(int peach)
{
peach=(peach+1)*2;
return peach;
}
主函数可以这么写:
printf("猴子最后一天剩多少个桃子:\n");
scanf("%d",&peach);
printf("猴子吃了多少天:\n");
scanf("%d",&day);
for(i=0;i<day;i++)
peach=Peach(peach);//使用了循环递归,每一步都要通过函数返回值才能正确进行下一步
printf("猴子第一天摘了%d个桃子。\n",peach);
好了,代码就如此简单实现了!参数可以任意设置!
下一步,才是介绍一个真正的难题,其实想通了还是挺简单的,那就是汉诺塔。
汉诺塔的代码网上已经爆料了很多了,我也是浏览了各种版本,在此只想写下来记录自己的学习历程。
汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。(废话… …不必在意)
其实,无论多少片,我们都可以用C语言描述并计算。
三根柱子,分别标记为a、b、c,
首先,一片圆盘时我们直接把A移动到C:
if(n==1)
printf("\t%c->%c\n",a,c);
其他情况,就要使用我们的递归调用了(有些烧脑):
else
{
move(n-1,a,c,b); //把c处的n-1个圆盘通过C处移动到b处
printf("\t%c->%c\n",a,c); //把a处的最后1个圆盘(最大的圆盘)移动到c处
move(n-1,b,a,c); //把b处上面的n-1个圆盘通过a处移动到c处
}
我们用n=2来举例说明以上代码:
n=2时(即a处两个圆盘),if语句不执行,执行else语句,
1.执行move(n-1,a,c,b):a处第一个盘移动到了b;
2.说明printf("\t%c->%c\n",a,c):a处最后一个盘移动到了c;(永远代表最后一个盘的移动)
3.执行move(n-1,b,a,c):b处的圆盘移动到了c.
Finish!结束两个盘时的递归,亦然,三个盘、四个盘道理同样如此。
主函数如下给出:
int n;
printf("请输入要移动的圆盘数:");
scanf("%d",&n);
move(n,'a','b','c');
Bingo!运行效果: