- Published on
汉诺塔问题(A,B,C三根柱子 0,1,2,3,4五个圆盘)
- Authors
- Name
- Pony Ma
A,B,C三根柱子 0,1,2,3,4五个圆盘
分治思想,把问题简化,拆分成子问题
我们只关注4号盘,要做的很简单,把0,1,2,3当做一个整体X,把X移到B柱(步骤一),4移到C柱(步骤二),再将X以到C柱(步骤三),结束
我们再来关注步骤一,刚才的整体X,再把他拆分,把0,1,2当做整体Y,把Y移动到C柱(步骤一),3移到到B柱(步骤二),再把Y移到到B柱(步骤三),结束
我们再来关注上述的步骤一,以此类推
拆分到最小的问题,就是只移动0号盘,移动一次即可就位
二进制解法
二进制简介
不管是怎么的进制,他们都是自相似的,规律都是一致的 重复计数若干次,进一位,再重复,再进一位
二进制只有两个数字0,1,它们叫bits(即二进制数位binary digits的简称) 我们从0开始数,当你数完0和1之后,bits就用完了,就要进到第二位,变成10 继续数,下一个是11,再继续,再次进位变为100
具体解法
用二进制来数数,计数的节奏就是解法 汉诺塔的算法和二进制计数都是自相似的过程
拆分到最小的问题,就是只移动0号盘,移动一次即可就位,这和二进制的计数规则是一致的,计数加一就需要进位,即进位到下一个圆盘
数第一位,第一位数字变化,就移动0号盘 数到第二位时,第二位数字变化,移动1号盘,第一位数字变化,就移动0号盘 数到第三位时,第三位数字变化,移动2号盘,第二位数字变化,移动1号盘,第一位数字变化,就移动0号盘
依次类推 第n位数字变化,就移动第n-1个盘
def solve_toh(n_disks):
if n_disks == 0:
return
solve_toh(n_disks - 1)
move_disk(n_disks - 1)
solve_toh(n_disks - 1)
===========================
def move(n, a, b, c):
if n == 1:
print(a, '-->', c)
return
# 把n-1个盘子从a移动到b
move(n - 1, a, c, b)
# 把最底下的盘子从a移动到c
move(1, a, b, c)
# 把n-1个盘子从b移动到c
move(n - 1, b, a, c)
move(3, 'A', 'B', 'C')
汉诺塔加强版
每次只能把圆盘移动到相邻的柱子上
实际原理也是一样的 我们只关注4号盘,把0,1,2,3当做一个整体X,把X移到B柱(步骤一),把X移到C柱(步骤二),4移到B柱(步骤三),再将X以到A柱(步骤四),4移到C柱(步骤五),再将X以到C柱(步骤六),结束
三进制解法
拆分成最小问题,即0号盘需移动两次才能就位 和三进制的计数方法是一致的,计数加二需要进一位,即进到下一个盘