Python零基础之汉诺塔谜题(解题思路,步骤,和步数)

Python零基础之汉诺塔谜题

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

# 定义一个函数解决汉诺塔游戏
# a b c三个柱子,假设所有的盘子初始都在a,a柱上有n≥1个盘子,要全部移动到c
# 目标
# 实现输出每一步:如第一步第1个盘子从a到b,第二步第2个盘子从c到a等
# 输出总步数

def fn(n, a, b, c):
    # 没有头绪,先模拟一下
    # n = 1时,bc为空: 第1个盘子a→c即可
    # n = 2时,因为要把最大的盘子放在c,所以第小一号的盘子不能放在c,所以第1个盘子a→b,第2个盘子a→c,第1个盘子b→c
    # n = 3时,实际上时把n=2的情况挪到b,然后把第三个盘子挪到c:即把fn(2)的输出步骤b和c交换位置,然后增加第三个盘子到C,然后把fn(2)输出步骤的a和b交换位置即得出
    # 推断结论,fn(n)就是把fn(n-1)输出的结果,b和c交换位置,然后加上第n个盘子移动到c,再加上fn(n-1)输出的结果,a和c交换位置,即可
    # 定义基线 n == 1的情况
    if n == 1:
        print('第 %d 个盘子从 %s → %s ' % (n,a,c))
        # 当 n == 1 打印完毕就不继续执行函数了,不需要返回值,返回None就行
        return
    # 根据推断结论创造递归条件
    fn(n - 1, a, c, b)
    # 移动最大盘的情况同n==1时的情况
    # 尝试了
    # fn(1,a,b,c)
    # 发现结果输出均为第一个盘子,所以直接打印
    print('第 %d 个盘子从 %s → %s ' % (n,a,c))
    fn(n - 1, b, a, c)


# 定义函数计算总步数
def step(n):
    m = 0
    for i in range(n):
        # 根据推断结论,本次的步数等于上次的步数m加1再加上次的步数m,即2m+1
        m = m * 2 + 1
    print('破解', n, '个盘子的汉诺塔所需要的最少步数为', m, '步')


# 定义主函数,主函数负责三个工作
# 获取输入,打印解谜步骤,打印最少步数
def main():
    n = int(input('请输入汉诺塔的盘子数量:'))
    # 用获取的盘子数n和字符'A','B','C'传参调用函数fn(n,a,b,c)
    fn(n, 'A', 'B', 'C')
    step(n)


if __name__ == '__main__':
    main()

  • 发现函数的迭代过程是解题的关键
  • 解题过程中原本想用string.replace实现参数互换,但是发现过于复杂,所以直接定义位置参数互换实现
  • 由于迭代过程不便引入步数计算,所以把步数计算单独写成了一个函数
  • 通过封装简化函数,使程序看起来更美
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingx3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值