首先,什麼是梵塔問題?
梵塔問題—有三個杆標號分別為a、b、c,初始時在a杆從上到下,按從小到大的順序放了n個圓盤。需要在有限步數下將n個圓盤平移到c,在平移的過程中,a、b、c桿上的圓盤自上到下都要服從圓盤大小自小到大。
那麼怎樣求解梵塔問題呢?–問題規約
對於梵塔問題,可以採用問題規約的思路將複雜的問題變成n個小問題的與或圖形式。
對於二梵塔問題,也是最簡單的問題。先將1號盤移到b,2號盤移到c,1號盤移到c。通過這三個簡單的問題就實現了二梵塔問題。
同樣對三梵塔,我們可以看成二梵塔和乙個圓盤的組合。也就是先將1、2號盤從a移送到b,將3號盤移送到c,再將1、2號盤從b移送到c。而二梵塔問題很好解決。
那麼對於n梵塔問題,就轉化為了先將1···n-1號盤從a轉移到b,將n號盤從a轉移到c,再將1···n-1號盤從b轉移到c。而將1~n-1號盤從a轉移到b以及從b轉移到c都是乙個n-1梵塔問題。不斷將問題進行規約,就變成了單個圓盤的與或圖形式。
四梵塔求解如下:
定義下圖狀態分別表示為(1111)、(1233),那麼最終狀態可以表示為(3333)
問題規約圖如下:
好了,到這裡我們已經直到如何求解了,但是怎麼進行程式設計實現呢?
程式設計實現
由上述的思考過程,對於梵塔的問題可以使用遞迴演算法:將n梵塔從a->c問題變成n-1梵塔a->b、n號從a->c以及n-1梵塔b->c的問題。而每個n-1梵塔問題變成n-2梵塔問題和n-1號圓盤。由此不斷進行歸約。
當歸約到1梵塔,直接輸出,否則就需要將問題歸約到1梵塔問題。從這個求解思路可以寫出遞迴演算法
void
fanta
(int n,
char a,
char b,
char c)
else
}
n代表的是n梵塔問題
這樣顯示是不是有點枯燥?
旦總說讓我做出動態顯示,否則就讓我和他體驗非洲有錢人枯燥的生活
為了不枯燥,定義三個棧m1、m2、m3分別表示a、b、c三個柱圓盤儲存情況
定義佇列fin用於儲存每一步的m1、m2、m3的情況
初始化棧m1,為裡面儲存值用於表示不同圓盤的大小,由於後進先出,所以棧頂元素小,初始化過程如下:
for
(int i =
1; i <= n; i++
) fin.
push
(m1)
; fin.
push
(m2)
;fin.
push
(m3)
;
當每進行一次圓盤的轉移,根據源和目的地進行出棧入棧:
voidgo(
char a,
char c)
else
if(a ==
'a'&& c ==
'c')
if(a ==
'b'&& c ==
'a')
if(a ==
'b'&& c ==
'c')
if(a ==
'c'&& c ==
'a')
if(a ==
'c'&& c ==
'b')
}
然後需要繼續更新fin:
fin.
push
(m1)
; fin.
push
(m2)
; fin.
push
(m3)
;
當所有過程結束後,將fin依次出隊,然後進行繪圖:
void
draw()
for(
int i =
1; i <= size2; i++
)for
(int i =
1; i <= size3; i++
)sleep
(2000);
cleardevice();}}
給大家看一下結果吧
動態顯示
如果對大家有用,完整檔案可以參考我的gitee(github又被牆了不能上傳檔案)
檔案鏈結
非常期待各位的star,實在是不想體驗枯燥的生活~~~
八皇后問題的動態顯示
編輯 八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n1 n1,而皇后個數也變成n2。而且僅當...
關於JS動態顯示的中文亂碼問題
剛剛做了乙個表單驗證,js控制的錯誤提示框老是亂碼,js檔案裡的文字卻顯示是正常的。全站都已經新增了 utf 8 編碼過濾器,在 裡也設定了js的編碼格式,但還是不管用。想了一陣才發現可能是js檔案的儲存格式跟 的編碼格式不一樣,去看了一下果真如此!插一句,在myeclipse裡右鍵js檔案選擇pr...
動態規劃 數塔問題求解 C 實現
file name digital tower.cpp function 動態規劃 數塔問題求解 c 實現 created on 2016年6月17日 author beijiwei qq.com 任何單位和個人不經本人允許不得用於商業用途 912 15 10 6 8 2 18 9 5 19 7 1...