小知識系列(3):Hanoi塔(漢諾塔,河內塔)
同樣,藉此來強化學習,但是說實話我寫這個感覺很玄。Hanoi塔是昨天剛學到的東西,想了很久,感覺還是沒有悟透,可能學到更多新東西,或產生了新的想法,或突然悟到了什麼,屆時會再做修改。
看了很多關於Hanoi塔的部落格,說實話都是一頭霧水,可能也是因為鄙人的理解能力有欠缺。一直看到一位博主的一篇講解才略有啟發,部落格↓↓↓
傳送門
(後續)
發現一位B站UP主的講解更加細緻,留下連結:↓↓↓
傳送門
OK,言歸正傳。
Hanoi塔起源是什麼?我們不多說,有興趣的可以查一下。
Hanoi塔的規則是什麼?
有三根柱子,將A柱子上所有的圓盤轉移到C柱子。
1.在小圓盤上不能放大圓盤。
2.在三根柱子之間一回只能移動一個圓盤。
3.只能移動在最頂端的圓盤。
具體操作?
我們從最簡單的開始:
一個盤:A→C;
兩個盤:A→B,A→C,B→C;
三個盤:A->C , A->B , C->B , A->C , B->A , B->C , A->C
一個盤的時候,直接由A柱到C柱
兩個盤的時候,把不是最大的一個放到B柱,然後把最大的從A放到C柱,再把B柱上的小盤放到C柱
三個盤的時候,步驟相同其實,就是把不是最大的放到B柱然後把最大的放到C柱,再借助A柱重複做一次兩個盤的情況的步驟(其實就是重複兩次)。
我們要解決n層Hanoi塔就要解決n-1層Hanoi塔,
我們要解決n-1層Hanoi塔就要解決n-2層Hanoi塔,
……
……
我們要解決3層Hanoi塔就要解決2層Hanoi塔,
我們要解決2層Hanoi塔就要解決1層Hanoi塔,
(分治思想)
總結一下:
只需要兩步來解決這個問題:
第一步:
把n-1個小盤,從A柱移動到B柱,
把第n個小盤,由A柱移動到C柱。
第二步:
把n-1個小盤,從B柱移動到C柱。←其實這一步就是換位置後重復第一步。
接下來做題有疑問 可以返回這裡檢視。
在這裡我先放上一道題以及完整的程式碼:
Description:
如圖所示的三根針,其中A針上穿好了由大到小的64片金片,不論白天黑夜,總有一個和尚在按照下面的法則移動金片:一次只移動一片,不管在哪根針上,小片必須在大片上面。和尚們預言,當所有的金片都從A針移到C針上時,世界就將在一聲霹靂中消失,這就是所謂的漢諾塔。請程式設計求出將A針上所有金片移到C上的步驟。
Input
標準輸入,一個整數N,表示有N個金片。
Output
標準輸出,輸出所有步驟,每一步驟佔一行。
Input Copy
3
Output
A->C
A->B
C->B
A->C
B->A
B->C
A->C
完整程式碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void f(int n,char a,char b,char c)
{
if(n==1)
cout<<a<<"->"<<c<<endl;
else
{
f(n-1,a,c,b);
cout<<a<<"->"<<c<<endl;
f(n-1,b,a,c);
}
}
int main()
{
int n;
cin>>n;
f(n,'A','B','C');
return 0;
}
我們要理解一個問題f()函式的4個位置分別的什麼意思?
例如f(n,‘A’,‘B’,‘C’)
這裡我們不是按照順序分析:
第二個位置,就是起始位置(位置1),也就是,你要把小盤從哪個柱子上拿走。
第四個位置,就是目標位置(位置3),也就是,你要把小盤全都按照順序放到這跟柱子上。
第三個位置,就是中轉位置(位置2),也就是,你要把最大的盤子,暢通無阻的從起始位置放到目標位置,其他的n-1個盤子必須放在這根柱子上。
第一個位置,就是我要轉移小盤的數量。
可能發現了,我又寫出位置1,位置2,位置3,為什麼呢?
這是為了不讓我們搞混與ABC搞混,ABC只是柱子的編號。
我們逐步分析,首先看main函式:
int main()
{
int n;
cin>>n;
f(n,'A','B','C');
return 0;
}
什麼意思?根據之前說過的,我們可以知道,**就是把n個小盤,由A柱經B柱中轉放到C柱上。**這也就是我們的目標。
再來看函式部分
void f(int n,char a,char b,char c)
{
if(n==1)
cout<<a<<"->"<<c<<endl;
else
{
f(n-1,a,c,b);
cout<<a<<"->"<<c<<endl;
f(n-1,b,a,c);
}
}
當只有一個盤子的時候,只要把A的盤子放到B即可。
如果大於1個,那麼f(n-1,a,c,b)先把n-1個小盤,由A經過C的中轉放到B。
然後再把第n個由A放到B
然後再把剩下的n-1個小盤由B經過A的中轉放到C
(步驟最開始有提到過)
TIP
1.理解過程,分治的思想,把一個大問題分成若干個小問題,如果你試圖自己置身於一個遞迴,我想不是天賦異稟,的確不一定能看的透……
所以你只要告訴他什麼情況該做什麼就好了,有些東西是一般人做不來的……比如鄙人……。
以上只是鄙人的拙見,如有不足之處,敬請斧正,如有難以理解的地方,亦可以指出。
相關文章
- 漢諾塔-PythonPython
- SQL 漢諾塔SQL
- 遞迴-*漢諾塔遞迴
- 漢諾塔詳解
- 漢諾塔和遞迴遞迴
- 奇怪的漢諾塔 - 題解
- 雙重河內塔I
- 課時24:遞迴:漢諾塔遞迴
- 遞迴求解漢諾塔問題遞迴
- Python實現:漢諾塔問題Python
- python3:遞迴解漢諾塔問題Python遞迴
- 雙色Hanoi塔問題
- PHP實現漢諾塔演算法PHP演算法
- 漢諾塔遊戲《演算法很美》遊戲演算法
- 漢諾塔的圖解遞迴演算法圖解遞迴演算法
- 【YbtOJ高效進階 遞推-2】奇怪漢諾塔
- 從漢諾塔遊戲理解python遞迴函式遊戲Python遞迴函式
- 課後習題4.9 Hanoi(漢諾)塔問題。這是一個經典的數學問題:古代有一個梵塔,塔內有3個座A,B,C,開始時A座上有64個盤子,盤子大小不等,大的在下,小的在上(見圖4.16)。有一個老和尚想把這
- 漢羅塔問題 java實現Java
- 魔法塔之謎(3)
- 方法論系列:用四個金字塔來說明金字塔原理
- 漢諾塔與二進位制、滿二叉樹的千絲萬縷二叉樹
- 簡單塔防小遊戲遊戲
- 寶塔使用
- 第二章 :查詢與排序-------遞迴經典問題——漢諾塔問題排序遞迴
- 塔塔通訊宣佈3C可持續發展戰略;承諾到2035年實現淨零排放
- 專訪《逃離塔科夫》漢化團隊:塔科夫正處於艱難過渡期
- 寶塔後臺解決寶塔相關問題
- 寶塔皮膚
- 魔法塔之謎
- 魔法塔總論(A)
- 格式塔(Gestalt)原理
- 寶塔常用命令,寶塔Linux皮膚命令大全!Linux
- JAVA漢諾塔遞迴 之SpringCloud企業分散式微服務雲架構快速開發平臺Java遞迴SpringGCCloud分散式微服務架構
- OpenCV計算機視覺學習(7)——影像金字塔(高斯金字塔,拉普拉斯金字塔)OpenCV計算機視覺
- hdu2084數塔
- AI能力金字塔AI
- 測試金字塔