漢諾塔解析(圖解)


ps:一時學不會也沒關系,過一個月再自己試試說不定就學會了

ps:圖片可能加載有點慢

題目:

三個柱子,標號為1,2,3

現在告訴你柱子1上套有n個盤,問你如何把全部盤從柱子1移到柱子3

注意:盤子順序必須時刻保持從上到下是從小到大的,一次只能移一個盤

 

基本思路:

現在有3個柱子,分別標號為1,2,3,然后會輸入一個n,代表初始的時候有幾個盤子

特殊說明:輸出過程的時候,把 1 -> 3 這樣的結果看作從柱子1移最上面那個盤子到柱子3

比如說當三個盤子時

3
1 -> 3
1 -> 2
3 -> 2
1 -> 3
2 -> 1
2 -> 3
1 -> 3

 

然后開始循序漸進地解決這題

#1:

假如把一開始的n個盤子看成兩部分,上面的小的和下面的大的,那么是不是只要三步就可以了

@1;把小的從1移到2

@2:把大的從1移到3

@3:把小的從2移到3

這里,1是起始柱子,2是中轉站的暫時柱子,而3是終點柱子,理解這個下面的拆分就容易理解些

 

#2:

剛剛用的是綁定法,但是剛剛的三步,如果上面綁定的小的不止一個盤子,實際上就不能實現,因為上面的一群盤子不可能直接一次性移過去(一次只能移一個盤)

可是我們剛剛對於那一群小盤的操作是不是可以又拆分呢

也就是一開始對n-1個盤和1個盤進行了移動,那n-1個盤又可以拆分為n-2個盤和1個盤的移動

 

#3:具體的實現及代碼

可以看到,就是把小的群移動到中轉站,然后大的底盤移到終點,最后小的群移動到終點

其中,每一次小的群移動又是新的拆分,即以小的群中最下面那個做新的地盤,其他的又是更小更新的小的群

 

也許有人會納悶為什么傳入hanno的實參老是變化,比如說

hanno(temp,end,start,n-1);

這是因為hanno的意義就是以第一個參數為起點,以第二個參數為終點,以第三個參數為中轉站,以第四個參數為當前還剩多少個盤的轉移,剛剛那一步temp也許是做中轉站,可是如果我們待會需要把temp的盤移到end那不僅是要把temp放第一個,end放第二個了嗎,如此一來,start只能放第三個當這次的中轉站

代碼:

#include<bits/stdc++.h>
using namespace std;
int n;
/*
 * hanno函數的意義是把當前n個盤從start移到end,用temp作為中轉站
 */
int hanno(int start,int end,int temp,int n)
{
    if(n-1>=1)//如果上面的部分起碼還有一個,就還要拆 
        hanno(start,temp,end,n-1);//把小的群移到中轉站,即從start移到temp,在這過程中end是充當臨時存放的地方

    printf("%d -> %d\n",start,end);//把底盤從start移到end

    if(n-1>=1)//如果上面的部分起碼還有一個,就還要拆 
        hanno(temp,end,start,n-1);//把小的群從中轉站移到終點,即從temp移到end,也就是這時候start是充當臨時存放的地方
}

int main()
{
    cin>>n;
    hanno(1,3,2,n);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM