課時24:遞迴:漢諾塔

那是個好男孩發表於2018-08-15

目錄:

   一、漢諾塔

   二、課時24課後習題及答案

 

*************

一、漢諾塔

*************

漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

對於遊戲的玩法,我們可以簡單分解為三個步驟
(1)將前63個盤子從X移動到Y上。
(2)將最底下的第64個盤子從X移動到Z上。
(3)將Y上的63個盤子移動到Z上。

仔細想下,在遊戲中,我們發現每次都只能移動一個圓盤,所以在移動的過程中顯然要藉助另外一根針才可以實施。也就是說,步驟(1)將1~63個盤子需要藉助Z移到Y上,步驟(3)將Y針上的63個盤子需要藉助X移到Z針上。

所以把新思路聚集為以下兩個問題:

問題一:將X上的63個盤子藉助Z移到Y上;
問題二:將Y上的63個盤子藉助X移到Z上。

 

可以拆分為3個步驟來實現:

問題一(“將X上的63個盤子藉助Z移到Y上”)拆解為:
(1)將前62個盤子從X移動到Z上。
(2)將最底下的第63個盤子移動到Y上。
(3)將Z上的62個盤子移動到Y上。

問題二(“將Y上的63個盤子藉助X移到Z上”)拆解為:
(1)將前62個盤子從Y移動到X上。
(2)將最底下的第63個盤子移動到Z上。
(3)將X上的62個盤子移動到Y上。

說到這裡,你發現了什麼?沒錯,漢諾塔的拆解過程剛好滿足遞迴演算法的定義,因此,對於如此難題,使用遞迴來解決,問題就變得相當簡單。參考程式碼:

def hanoi(n, x, y, z):
    if n == 1:
        print(x, ' --> ', z)
    else:
        hanoi(n-1, x, z, y) # 將前n-1個盤子從x移動到y上
        print(x, ' --> ', z) # 將最底下的最後一個盤子從x移動到z上
        hanoi(n-1, y, x, z) # 將y上的n-1個盤子移動到z上

n = int(input('請輸入漢諾塔的層數:'))
hanoi(n, 'X', 'Y', 'Z')

看!這就是遞迴的魔力。

 

*******************************

二、課時24課後習題及答案

*******************************

相關文章