演算法 漢諾塔加強版 陣列

2021-09-28 14:37:40 字數 1962 閱讀 8778

漢諾塔問題中限制不能將一層塔直接從最左側移動到最右側,也不能直接從最右側移動到最左側,而是必須經過中間。求當有n層塔的時候移動步數。

輸入第一行為用例個數, 每個測試用例輸入的第一行為n。

移動步數。12

# 求加強版漢諾塔,不能直接從左邊移動到右邊,也不能直接從右邊移動到左邊,求從左邊移動到右邊的總移動次數

# 此題用遞迴是最簡單的,可以發現規律,hanoi(n)= 3* hanoi(n-1) +2

from enum import enum

defhanoi

(num)

:# 遞迴方法

if num ==1:

return

2else

:return

3* hanoi(num -1)

+2# 非遞迴方法:用棧代替遞迴

# 加強版漢諾塔有2大原則:1)小壓大:即小的必須在大的上面;2)相鄰不可逆:l->m和m->l是相鄰,其不可逆,否則就來回走了

# 由此推導出核心結論:1)第一步肯定是l->m;2)在走最少步驟的情況下,每次只有乙個動作符合2大原則,其餘3個動作均不符合。

# 對於結論2:例如,前乙個動作是l->m,則,根據小壓大原則,l->不會發生,根據相鄰不可逆原則,m->l動作也不會發生,根據小壓大原則,m->r和r->m只有乙個會滿足

# 因此,每次迴圈各個動作都執行一遍,但進行判斷,只有滿足2大原則的才移動

defhanoi_stack

(num)

: action = enum(

'action',(

'no'

,'ltom'

,'mtol'

,'mtor'

,'rtom'))

# 列舉動作

ls =

[num +1]

# 棧底要夠大,使得判斷小壓大時滿足條件

ms =

[num +1]

rs =

[num +1]

for i in

range

(num)

: record =

[action.no]

# 記錄前一動作

step =

0while

len(rs)

!= num +1:

# 迴圈直到全部都到rs,每次迴圈對每個動作都呼叫一次移動函式

step += fstacktotstack(record, action.mtol, action.ltom, ls, ms)

step += fstacktotstack(record, action.ltom, action.mtol, ms, ls)

step += fstacktotstack(record, action.mtor, action.rtom, rs, ms)

step += fstacktotstack(record, action.rtom, action.mtor, ms, rs)

return step

deffstacktotstack

(record, preact, nowact, fstack, tstack)

:if record[0]

!= preact and fstack[-1

]< tstack[-1

]:# 進行判斷該動作是否符合2大原則,滿足才進行移動))

record[0]

= nowact

return

1return

0nums =

int(

input()

)for n in

range

(nums)

: num =

int(

input()

)# print(hanoi(num))

print

(hanoi_stack(num)

)

漢諾塔加強版

這是漢諾塔1的公升級版。大梵天創造世界的時候做了三根金剛石柱子 a,b,c 在a柱子上從下往上按照大小順序摞著n片 圓盤。大梵天命令啊仁把圓盤從下面開始按大小順序重新擺放在c柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動乙個圓盤。大梵天想為難啊仁,不想讓他那麼早去約會,於是想讓...

演算法 漢諾塔 Python 版

題目 漢諾塔給出最優解,如果對漢諾塔的定義有不了解,請翻看資料結構教材。除了最基本的之外,還有一題,給定乙個陣列,arr 2,3,1,2,3 其含義是這是乙個有5個圓盤的漢諾塔,每乙個數字代表這個圓盤所在的位置,1代表左邊的柱子,2代表中間,3代表右邊。給出這個序列代表了漢諾塔移動的第幾步,如果該步...

漢諾塔演算法

最簡步驟 2的n次冪 1 為了實現 n個盤從 借助c 從a 移動到 b 思路如下 首先考慮極限當只有乙個盤的時候 只要 盤直接從 a b即可 那麼當有2個盤的時候就只要先把1號盤從a c 然後 把2號盤 a b 再 把 2好盤從 c b 那麼當有n個盤的時候你只要先把 n 1個 盤 借助 b 移動到...