汉诺塔
法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
要解决这个问题,其思路如下:
(1)将前63个盘子从A移动到B上,确保大盘在小盘底下。
(2)将最底下的第64个盘子从A移动到C上。
(3)将B上的63个盘子移动到C上。
解决问题的思路有了,关键在于步骤(1)和步骤(3)如何执行。由于每次只能移动一个圆盘,所以在移动过程中,显然要借助另外一根针才可以实施。也就是说,步骤(1)将1~63个盘子需要借助C移到B上,步骤(3)将B上的63个盘子借助A移动到C上。
所以,把新的思路聚集为以下两个问题:
问题一:将A上的63个盘子借助C移动到B上;
问题二:将B上的63个盘子借助A移动到C上。
而相应的问题一和问题二的解决方法跟刚才第一个问题的思路是一样的。
问题一(将A上的63个盘子借助C移动到B上)可拆解为:
(1)将前62个盘子从A移动到C上,确保大盘在小盘下。
(2)将最底下的第63个盘子移动到B上。
(3)将C上的62个盘子移动到B上。
问题二(将B上的63个盘子借助A移动到C上)可拆解为:
(1)将前62个盘子从B移动到A上,确保大盘在小盘下。
(2)将最底下的第63个盘子移动到C上。
(3)将A上的62个盘子移动到C上。
所以,这个难题可以用递归来解决:
# 汉诺塔问题
def hanoi(n, a, b, c): # 将第n层从a借助b移动到c
if n == 1:
print(a, '-->', c) # 如果只有一层,直接从a移动到c
else:
hanoi(n-1, a, c, b) # 将前n-1个盘子从a移动到b上
print(a, '-->', c) # 将最底下的第64个盘子从a移动到c上
hanoi(n-1, b, a ,c) # 将b上的63个盘子移动到c上
n = int(input('请输入汉诺塔的层数:'))
hanoi(n, 'A', 'B', 'C')