智力题:汉诺塔移动过程模拟

智力题:汉诺塔移动过程模拟

首页休闲益智乐高汉诺塔更新时间:2024-05-11

汉诺塔问题是程序设计中的经典递归问题。

汉诺塔游戏:有n个盘,A为起始柱,B为借力柱,C为目标柱,n个盘从小到大编号为1、2、3、...、n-1,n,求需要移动的步数最优解F(N).

汉诺塔游戏的规则如下:

1、每次只能移动一个圆盘。

2、圆盘只能放在空柱子上或者比自己大的圆盘上。

3、不能将圆盘放在比自己小的圆盘上。

1、解题思路:

(1)、当n=0,则没有盘,无需移动,故F(n=0)=0

(2)、当n=1,则直接从A柱移动到C柱即可,故F(n=1)=1

(3)、当n=2时,则需要需要的步数F(n=2)=3:

2个盘汉诺塔解法如下图所示:

第1步:将盘1从A柱移动到B柱,需要移动次数为1

第2步:将盘2从A柱移动到C柱,需要移动次数为1

第3步:将盘1从B柱移动到C柱,需要移动次数为1

综上,F(n=2)=1 1 1

2个盘汉诺塔解法

(4)、当有n个盘时,将盘1至盘n-1当作一个整体盘,则问题就转化为整体盘、盘n的两个盘汉诺塔问题了,故需要移动的次数为:F(n)=F(n-1) 1 F(n-1)

n个盘汉诺塔需要移动次数记为F(n),则n个盘汉诺塔解法如下图所示:

第1步:将整体盘(盘1至盘n-1)从A柱移动到B柱,则需要移动次数为F(n-1)

第2步:将单个盘n从A柱移动到C柱,则需要移动次数为1次

第3步:将整体盘(盘1至盘n-1)从B柱移动到C柱,则需要移动次数为F(n-1)

综上:F(n)=F(n-1) 1 F(n-1)=2*F(n-1) 1

n个盘汉诺塔问题(递归求解法)

2、递归求解F(n)

由上面的解题思路,可得n个汉诺塔需移动的步数的递归公式为:F(n)=2F(n-1) 1,其中n>=1,F(0)=0,F(1)=1,经举例发现F(n)=2^n-1(n>=2)。

(1)当n=0时,F(n=0)=0

(2)当n=1时,F(n=1)=1=2^0

(3)当n=2时,F(n=2)=2F(n-1) 1=2F(1) 1=2*1 1=2 1=2^1 2^0=2^2-1=3

(4)当n=3时,F(n=3)=2F(n-1) 1=2F(2) 1=2*(2^1 2^0) 2^0=2^2 2^1 2^0=2^3-1=7

(5)当n=4时,F(n=4)=2F(n-1) 1=2F(3) 1=2*(2^2 2^1 2^0) 2^0=2^3 2^2 2^1 2^0=2^4-1=15

观察上式可得,F(n)=2F(n-1) 1=2^n-1,下面用数学归纳法证明F(n)=2^n-1成立即可。

3、数学归纳法证明F(n)=2^n-1,证明过程如下:

(1)当n=0时,F(n=0)=0=2^0-1

(1)当n=1时,F(n=1)=2F0) 1=2*0 1=1=2^1-1

(2)当n=2时,F(n=2)=2F(n-1) 1=2F(1) 1=2*1 1=3=2^2-1

(3)当n=3时,F(n=3)=2F(n-1) 1=2F(2) 1=2*3 1=7=2^3-1

(4)当n=4时,F(n=4)=2F(n-1) 1=2F(3) 1=2*7 1=15=2^4-1

(5)假设当n=k时,F(n=k)=2F(k-1) 1=2^k-1成立,则只需证明当n=k 1时,等式也成立即可

(6)当n=k 1时,F(n=k 1)=2F(k) 1=2*( 2^k-1 ) 1=2*2^k-2 1=2^(k 1)-1,即当n=k 1时,F(n=k 1)=2^(k 1)-1,等式成立,故F(n)=2^n-1(n>=2)等式成立。

综上:n个盘的汉诺塔需要移动的步数最优解:F(N)=2^n-1.

4、python模拟实现汉诺塔移动过程:

count=0 # 移动次数 # n个盘汉诺塔从A柱移动C柱,B柱为借力柱移动过程模拟,list_start为起始柱的盘子 def hannuota_list(list_start,A_start,B_min,C_end): global count n=len(list_start) if n==0: print(f'无需移动,已移动次数{count}') elif n==1: count=count 1 print(f'第{count}次移动: 盘{list_start[n-1]}:{A_start} --> {C_end}') # 整体盘从起始柱 A_start 移动到目标柱 C_end else: list_aa=[list_start[x] for x in range(n-1)] # 盘切分成两部分 #list_bb=list_start[n-1] # 最后一个盘 hannuota_list(list_aa,A_start,C_end,B_min) # 整体盘从起始柱 A_start 移动到 借力柱 B_min,目标柱 C_end 为过渡 count=count 1 print(f'第{count}次移动: 盘{list_start[n-1]}:{A_start} --> {C_end}') # 整体盘从起始柱 A_start 移动到目标柱 C_end hannuota_list(list_aa,B_min,A_start,C_end) # 整体盘从借力柱 B_min 移动到 目标柱 C_end,起始柱 A_start 为过渡 # 主程序: if __name__ == '__main__': n=4 list_a=[x 1 for x in range(n)] # 生成盘号分别为1,2,3,...,n-1,n的盘 print(f'{n}个汉诺塔从上往底部的盘号依次为:{list_a}') print() print(f'{n}个盘汉诺塔移动模拟过程如下: ') count=0 hannuota_list(list_a,A_start='A柱',B_min='B柱',C_end='C柱') # 移动4个盘,起始柱为A柱,目标柱为C柱,借力柱为B柱

运行结果如下:

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved