以前在学校搞蓝桥杯的时候遇到过这个问题,最近又碰到了,就复习一下

什么是汉诺塔问题?

引用 wikipedia 的解释

有三根杆子A,B,C。A杆上有 N 个 (N>1) 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:
每次只能移动一个圆盘;
大盘不能叠在小盘上面。
提示:可将圆盘临时置于 B 杆,也可将从 A 杆移出的圆盘重新移回 A 杆,但都必须遵循上述两条规则。
问:如何移?最少要移动多少次?

把三根杆子称为:

起始杆:圆盘最初所在的杆

中转杆:用于临时放圆盘的杆

目标杆:要把圆盘移到这里来

具体到编程就是

def move(n,a,b,c):
'''
n: 需要移动的圆盘数量
a: 起始杆
b: 中转杆
c: 目标杆
'''
	pass

思路

如果只有一个盘

如果只有一个盘,不需要中转,直接从 A → C 即可

def move(n,a,b,c):
	if n == 1:
		print(a,'->',c)

如果有多个盘

两个盘时

将 起始杆 上的圆盘从上到下标记为 1,2

步骤1:将 1 从 A 移动到 B

步骤2: 将 2 从 A 移动到 C

步骤3: 将 1 从 B 移动到 C

三个盘时

将 起始杆 上的圆盘从上到下标记为 1,2,3

步骤1:将 1 从 A 移动到 C

步骤2:将 2 从 A 移动到 B

步骤3:将 1 从 C 移动到 B

步骤4:将 3 从 A 移动到 C

步骤5:将 1 从 B 移动到 A

步骤6:将 2 从 B 移动到 C

步骤7:将 1 从 A 移动到 C

我们可以把上面的步骤分为 3 个阶段

步骤1-4:将 3 移动到 C

步骤5-6:将 2 移动到 C

步骤7:将 1 移动到 C

如果更多盘呢?

我们来观察上面的 3 个阶段,不难发现,每一个阶段的任务其实就是

把当前没有放到目标杆的最大圆盘放到目标杆

所以其实每一步所执行的都是相同的内容,只是问题的规模更小了 —— 递归

那么为了实现 把当前没有放到目标杆的最大圆盘放到目标杆 就又需要 3 步:

把 A 上的圆盘从上至下命名为:1,2,3……,n-1,n

  1. 把 A 上的 从 1 到 n-1 移动到 B
  2. 把 A 上的 n 移动到 C
  3. 把 B 上的 从 1 到 n-1 移动到 C
def move(n,a,b,c):
'''
n: 需要移动的圆盘数量
a: 起始杆
b: 中转杆
c: 目标杆
'''
	if n == 1:
		print(a,'->',c)
  	else:
		move(n-1,a,c,b) # 把 A 上的 从 1 到 n-1 移动到 B
		move(1,a,b,c) # 把 A 上的 n 移动到 C
		move(n-1,b,a,c) # 把 B 上的 从 1 到 n-1 移动到 C

因此,答案就出来了

Q.E.D.


此 生 无 悔 恋 真 白 ,来 世 愿 入 樱 花 庄 。