haskell 基础题解(35)

汉诺塔

【题目】传说印度的一个神庙中,供有天神制成的“汉诺塔”。它是三根柱子。在一根柱子上,从上到下,由小到大叠放着64个金盘。僧人们要把这些金盘搬到另一根柱子上。规则是:一次只能移动一个圆盘。大盘不能叠在小盘的上面。
那么,完成这个任务,最少要移动多少次呢?
在这里插入图片描述
这个问题难点也是大整数运算。
大整数的构造见【问题34】。

另外还有一个迷惑人的地方:比如要把这些盘子都移到c柱,那第一步是把最小的那个盘放到B柱好呢?还是放到C柱好呢?肯定不能随意。
其实大可不必纠结。人家没问你怎么移动,只是问最少多少步。
这个问题,只要倒着考虑就迎刃而解了。
1)要把所有盘移到C柱,肯定要把最大盘的上边那些盘都拿开。
2) 拿到哪里呢?肯定C柱上什么都不能有,不然最大那个盘放不上去。
3)得出结论:必须把最大盘上那些都移到B柱上,然后最大盘上C,然后B柱上那些再上C。

现在问题分解为:最大盘上的那些移到B上去,最少多少步?
这个问题与当前任务是相似的。只是规模小1而已。这提示我们可以用递归。

上代码

hanoi :: Int -> Integer
hanoi 1 = 1
hanoi n = hanoi (n-1) * 2 + 1 --- n上面的移走 + n入位 + n上面的移来。

main :: IO ()
main = print $ hanoi 64

现在,把问题稍微变一下,给定盘子数目,要从A柱整体移到C柱,求第一步是先到B,还是先到C?
显然,1 个盘是先到c,2个盘是先到B。

这其实也可以用递归思路。
n要到C, n-1个必须到B,所以n-2个又必须到C, 。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值