漢諾塔問題:
問題來源:漢諾塔來源於印度傳說的一個故事,上帝創造世界時作了三根金剛石柱子,在一根柱子上從上往下從小到大順序摞着64片黃金圓盤。上帝命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一回只能移動一個圓盤,只能移動在最頂端的圓盤。有預言說,這件事完成時宇宙會在一瞬間閃電式毀滅。也有人相信婆羅門至今仍在一刻不停地搬動着圓盤。恩,當然這個傳說並不可信,如今漢諾塔更多的是作為一個玩具存在。
現在有n個圓盤從上往下從小到大疊在第一根柱子上,要把這些圓盤全部移動到第三根柱子要怎么移動呢?請找出需要步驟數最少的方案
因此我們可以將問題簡化描述為:n個盤子和3根柱子:A(源)、B(備用)、C(目的),盤子的大小不同且中間有一孔,可以將盤子“串”在柱子上,每個盤子只能放在比它大的盤子上面。起初,所有盤子在A柱上,問題是將盤子一個一個地從A柱子移動到C柱子。移動過程中,可以使用B柱,但盤子也只能放在比它大的盤子上面。
因此我們得出漢諾塔問題的以下幾個限制條件:
1.在小圓盤上不能放大圓盤。
2.在三根柱子之間一回只能移動一個圓盤。
3.只能移動在最頂端的圓盤。
首先,我們從簡單的例子開始分析,然后再總結出一般規律。
當n = 1的時候,即此時只有一個盤子,那么直接將其移動至C即可。移動過程就是 A -> C
當n = 2的時候,這時候有兩個盤子,那么在一開始移動的時候,我們需要借助B柱作為過渡的柱子,即將A柱最上面的那個小圓盤移至B柱,然后將A柱底下的圓盤移至C柱,最后將B柱的圓盤移至C柱即可。那么完整移動過程就是A -> B , A -> C , B -> C
當n = 3的時候,那么此時從上到下依次擺放着從小到大的三個圓盤,根據題目的限制條件:在小圓盤上不能放大圓盤,而且把圓盤從A柱移至C柱后,C柱圓盤的擺放情況和剛開始A柱的是一模一樣的。所以呢,我們每次移至C柱的圓盤(移至C柱后不再移到其他柱子上去),必須是從大到小的,即一開始的時候,我們應該想辦法把最大的圓盤移至C柱,然后再想辦法將第二大的圓盤移至C柱......然后重復這樣的過程,直到所有的圓盤都按照原來A柱擺放的樣子移動到了C柱。
那么根據這樣的思路,問題就來了: 如何才能夠將最大的盤子移至C柱呢? 那么我們從問題入手,要將最大的盤子移至C柱,那么必然要先搬掉A柱上面的n-1個盤子,而C柱一開始的時候是作為目標柱的,所以我們可以用B柱作為"暫存"這n-1個盤子的過渡柱,當把這n-1的盤子移至B柱后,我們就可以把A柱最底下的盤子移至C柱了。
而接下來的問題是什么呢? 我們來看看現在各個柱子上盤子的情況,A柱上無盤子,而B柱從上到下依次擺放着從小到大的n-1個盤子,C柱上擺放着最大的那個盤子。 所以接下來的問題就顯而易見了,那就是要把B柱這剩下的n-1個盤子移至C柱,而B柱作為過渡柱,那么我們需要借助A柱,將A柱作為新的"過渡"柱,將這n-1個盤子移至C柱。
根據上面的分析,我們可以抽象得出這樣的結論:
漢諾塔函數原型:
我們把n個盤子從A柱移動至C柱的問題可以表示為: Hanio(n,A,B,C); 那么從上面的分析得出: 該問題可以分解成以下子問題:
第一步:將n-1個盤子從A柱移動至B柱(借助C柱為過渡柱)
第二步:將A柱底下最大的盤子移動至C柱
第三步:將B柱的n-1個盤子移至C柱(借助A柱為過渡柱)
…….
因此利用python編程規則其完整代碼如下所示:
def hanoi(n,x,y,z):
if n==1:
print(x,"-->",z)
else:
hanoi(n-1,x,z,y)
print(x,"-->",y)
hanoi(n-1,y,x,z)
while True:
n=int(input("請輸入漢諾塔的層數:"))
hanoi(n,"x","y","z")