漢諾塔問題中限制不能將一層塔直接從最左側移動到最右側,也不能直接從最右側移動到最左側,而是必須經過中間。求當有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 移動到...