漢諾塔問題探討

漢諾塔問題探討

原題目

​ 有三根柱子,每根柱子上一開始都是空的。我們把這三個柱子編號爲1, 2, 3,現在,第一根柱子上有N 個盤子按照尺寸從小到大排列,我們的目的是把這些盤子按順序從第一根柱子轉移到第三根上。在移動過程中有要求,即每個柱子上要想往上疊加盤子,只能疊加比它尺寸小的盤子。那麼我們該怎麼挪?

Link 提交評測區(codevs)

思路

​ 我們先想這樣一個思路,就是我們先定義一個函數kansu(x,y,z) ,這個函數的功能是把x 柱子上的y 個盤子按照順序移動到z 柱子上。在想的過程中,一定不要考慮要怎麼移動,只要知道我們要移動就好了。這樣,調用一遍kansu(A,N1,B) ,現在B 柱子上就有依次疊好的N1 個盤子了,A 上就只剩下最大的那一個,C 上一個也沒有。現在我們分析一下,A 上只有一個最大的,也就是說可以在A 上放置任意一個盤子。那麼,把A 上剩下的那個最大的移動到C 上,那麼C 上的那個就是最大的了。現在,A 是空的,B 上有N1 個,C 上有一個最大的。

​ 這裏大家注意一下,一開始A 柱子上有N 個盤子,B 柱子和C 柱子上都沒有盤子,而現在A 上沒有,BN1 個,C 上一個最大的。正因爲C 上有一個最大的,所以上面可以放任意一個盤子,也就等價於空的。這樣,我們就把我們要解決的移動N 個盤子的問題簡化成了移動N1 個盤子的問題(只是位置不同),而這正是利用了遞歸的思想。

​ 現在我們完成了把一個最大的挪到C 上的任務了,那麼我們最終的任務就明瞭了,就是把每次的最大的挪到C 柱子上,這樣最大的越積越多,積到N 個我們就得到結果了。

僞代碼

S1:利用Kansu(A, N - 1, B)將A上的N - 1個盤子按照順序移動到B柱子上
S2:利用Move(A, C)將A柱子上剩下的一個最大的盤子移動到C柱子上
S3:利用Kansu(B, N - 2, A)將B上的N - 2個盤子按照順序移動到B柱子上
......
最後在一個一個Move的過程中,C上就按照從大到小的順序壘好了N個盤子。

C++代碼

#include <cmath>
#include <iostream>

void Hanoi(const int n, const int A, const int B, const int C)
{

    if (n > 0)
    {
        Hanoi(n - 1, A, C, B);
        std::cout << n << " from " << char (64 + t.x)  << " to " << char (64 + t.y) << '\n';
        Hanoi(n - 1, C, A, B);
    }
}


int main(int argc, char ** argv)
{
    int n;
    std::cin >> n;
    std::cout << std::pow(2, n) - 1 << std::endl;
    // 2^n - 1 表示步數總數
    Hanoi(n, 1, 3, 2);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章