经典编程问题(13)汉诺塔

背景

汉诺塔,又称河内塔(hanoi),源于印度古老的传说。
该传说中要求在三个柱子间移动金质的圆盘,规则是:

  • 每次只能移动一个盘子
  • 大盘子不能放在小盘子的上方
  • 开始的时候,在某根柱子上有 n 个盘子,另两柱空着

题目

三根柱子编号 0, 1, 2
在 0 号柱子上有 n 个盘子,可以用 list 表示 [5, 4, 3, 2, 1]
数字的大小表示盘子的大小,List 尾为柱子的上端
今,要把 0 号柱的所有盘子最终移动到 2 号柱

请打印出移动的过程,以及过程中每个柱子的状态。

分析

题目看着好像挺不好处理
如果,只是问需要移动几次,还好办点。
其实不困难。
比如,要求把 n 个盘 从 a 柱移动到 c 柱,
这里的 n , a, c 都是变量。
那么,只需要:

  1. 先设法把上边的 n-1 个盘从 a 柱暂时放到 b 柱
  2. 再把最大的一个盘从 a 移动到 c
  3. 再设法把 n-1 个盘从 b 柱移动到 c

注意,b是个变量,与 a, c 有什么关系呢?
其实很简单: b = 3 - a - c
全部秘密就这么多了,上代码

代码

# 汉诺塔
def hanoi(n):
	da = [[], [], []]
	da[0] = list(range(1,n+1))
	da[0].reverse()

	print(da)

	# 把 n 盘子从 a号柱移动到 b号柱
	def f(a, b, n):
		if n == 1:
			da[b].append(da[a].pop())
			print(a, ' -> ', b, ' : ' , da)
			return
		c = 3 - a - b
		f(a, c, n-1)
		f(a, b, 1)
		f(c, b, n-1)

	f(0, 2, n)

################
hanoi(3)

这是 n = 3 时的情景,运行效果是:

[[3, 2, 1], [], []]
0  ->  2  :  [[3, 2], [], [1]]
0  ->  1  :  [[3], [2], [1]]
2  ->  1  :  [[3], [2, 1], []]
0  ->  2  :  [[], [2, 1], [3]]
1  ->  0  :  [[1], [2], [3]]
1  ->  2  :  [[1], [], [3, 2]]
0  ->  2  :  [[], [], [3, 2, 1]]

还是有疑惑?

去看视频吧,如下:
汉诺塔的移动步骤
祝编程愉快!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值