1. 程式人生 > >hanoi塔經典遞迴演算法

hanoi塔經典遞迴演算法

法國數學家愛德華·盧卡斯曾編寫過一個印度的古老傳說:在世界中心貝拿勒斯(在印度北部)的聖廟裡,一塊黃銅板上插著三根寶石針。印度教的主神梵天在創造世界的時候,在其中一根針上從下到上地穿好了由大到小的64片金片,這就是所謂的漢諾塔。不論白天黑夜,總有一個僧侶在按照下面的法則移動這些金片:一次只移動一片,不管在哪根針上,小片必須在大片上面。僧侶們預言,當所有的金片都從梵天穿好的那根針上移到另外一根針上時,世界就將在一聲霹靂中消滅,而梵塔、廟宇和眾生也都將同歸於盡。

額額額額~~~~

傳說有點可怕,但還是想知道多長時間可以完成任務~~~~

這裡用到了遞迴的手法 :假設有n片,移動次數是f(n).顯然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此後不難證明f(n)=2^n-1。n=64時,

假如每秒鐘一次,共需多長時間呢?一個平年365天有31536000 秒,閏年366天有31622400秒,平均每年31556952秒,計算一下:

18446744073709551615秒

這表明移完這些金片需要5845.54億年以上,而地球存在至今不過45億年,太陽系的預期壽命據說也就是數百億年。真的過了5845.54億年,不說太陽系和銀河系,至少地球上的一切生命,連同梵塔、廟宇等,都早已經灰飛煙滅。

好了,娛樂結束,回到正題:

題意很簡單,三個柱子,最左邊柱子上有n個盤子(也有叫碟子的),要求把盤子都移動到最右邊的柱子上,移動規則如下:

1. 每次只能從一個柱子的最上面移動一個碟子到另外一個柱子上。

2. 不能將大碟子放到小碟子的上面。

假設只有一個盤子,直接把它移到C柱子上;

兩個盤子,先把第一個移到B上,然後把第二個移到C上,最後把第一個移到C上;

三個盤子,先把前兩個移到B上,然後把最後一個移到C上,最後把前兩個移到C上;

......

n個盤子,先把前n-1個移到B上,然後把最後一個移到C上,最後把前n-1個移到C上;

所以每次需要三大步就可以完成,很簡單吧;

BUT~~~程式碼呢???

彆著急,自己先嚐試敲一遍;

程式碼奉上

    #include <bits/stdc++.h>
    int count=0;      //用來計步;
    void hanoi(int n, char A, char B, char C)  //n為盤子的個數,A是最左邊柱子,C是最右邊柱子,B是中間柱子;
    {
        if(n==1){
            printf("The %d step : %c -> %c\n",++count,A,C);  //只有一個盤子,直接從A移動到C;
            return;
        }
        hanoi(n-1, A, C, B);             //n-1個盤子,把前n-1個移動到B柱子,最後一個移動到C柱子,再把n-1個從B移動到C;
        printf("The %d step : %c -> %c\n",++count,A,C);
        hanoi(n-1, B, A, C);             //第n個盤子移完後,從B上把n-1個移到C上;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        hanoi(n, 'A', 'B', 'C');
        return 0;
    }