跳馬周遊c 漢諾塔,n皇后,跳馬問題彙總

2021-10-13 14:21:15 字數 2341 閱讀 4375

軟體課講了這些問題,這次順便總結下。

說白了也就是:遞迴,回溯,深搜或者廣搜。

1.漢諾塔

漢諾塔題目:

假設有a, b, c 3個軸,有n個直徑各不相同,

從小到大依次編號為1,2,3,…,n的圓盤

按照從小到大的順序疊放在a軸上。現在要求

將這n個圓盤移至c軸上並仍然按照同樣順序

疊放,但圓盤移動時必須遵守下列規則:

1.每次只能移動乙個圓盤,它必須位於某個

軸的頂部。

2.圓盤可以插在a,b,c中任一軸上。

3.任何時刻都不能將乙個較大的圓盤壓在較小

的圓盤之上。

但是這畢竟是神話,不過當把64個金片全部放到另外一根針時,確實要很長很長一段時間。

讓我們來看看需要多長時間。

首先,我們找出遞推關係:

f(n + 1) = 2*f(n) + 1

至於這個怎麼得到的可以畫圖看看。

把遞推關係算出來後,也就是:

f(n) = 2^n-1

那麼當n=64時,是多少?

f(64)= 2^64-1=18446744073709551615

假如每秒鐘一次,共需多長時間呢?一年大約有 31536926 秒,計算表明移完這些金片需要5800多億年,比地球壽命還要長,事實上,世界、梵塔、廟宇和眾生都已經灰飛煙滅。

好吧,說了那麼多,還是步入正題。

漢諾塔的實現有遞迴和非遞迴兩種情況,遞迴的很常見,也很簡單,非遞迴實際上就是二叉樹的中序遍歷。也可以認為是棧的實現。

遞迴的版本:

/*遞迴實現*/#includeusingnamespacestd;//把n號圓盤從x移到y,並列印出。voidmove(intn,charx,chary)

cout<

}//把前n個通過b從a移到cvoidhanoi(intn,chara,charb,charc)

intmain()

elseif(flag)

search(cur+1);//如果合法,繼續}

}intmain()

cout<

cin>>n;

search(0);

cout<

對於這個問題,還可以用輔助空間來提高演算法的效率: 增加輔助空間vis來判斷是否有其他皇后已經在列和對角線上。

#includeusingnamespacestd;intqueen[100];intn;//n皇后inttot=0;//解法種數intvis[3][100];//輔助空間voidsearch(intcur)

else

}intmain()

memset(vis,0,sizeof(vis));

cout<

cin>>n;

search(0);

cout<

3.跳馬問題:

據說此題證明可以用組合數學中的哈密頓環。

組合數學確實博大精深,看過一段時間的組合數學,感覺和實際聯絡的很多,orz.

此題有兩種版本:

①:給定乙個n*n的棋盤,起始點在(0,0)處,要求求出有多少種方法,可以不重複的遍歷棋盤上所有的點。

規則:1.馬走日字

2.走過的點就不能再走了

此題和上面的n皇后類似,是標準的dfs。

分析:從起始點開始,每次遍歷八種方向,直到邊界條件,並輸出。

以下是跳馬問題一的原始碼:

/*馬跳棋盤問題*/#includeusingnamespacestd;constintn=10;inta[n][n]=;intcnt=0;voidhorse(inta,intb,intt);

voidhorse(inta,intb,intt)

, y[4]=;if(t==n*n+1)cnt++;for(inti=0; i<4;++i)for(intj=0; j<4;++j)

{if(x[i]==y[j]||x[i]==-y[j])continue;if(a+x[i]>=0&&a+x[i]=0&&b+y[j]

a[a+x[i]][b+y[j]]=t;

horse(a+x[i], b+y[j], t+1);

a[a+x[i]][b+y[j]]=0;

第二個版本: ②:設有右圖所示的乙個棋盤,在棋盤上的a點,有乙個中國象棋的馬,並約定馬走的規則:

規則:1. 馬走日字

2. 馬只能向右走。

試找出所有從a到b的途徑。

此題也是oi上很有名的騎士問題。

此題似乎比較適合bfs.

還沒嘗試過。

讓我再想想,好像還有八數碼和素數環問題沒寫。

不過在hdoj上遇到過乙個素數環的題目:

有興趣可以做下。

對於dfs和bfs更多的題目,可以在我部落格右上角搜尋欄裡輸入dfs或bfs,會出來相應題目。

八皇后和漢諾塔問題

三個盤子的漢諾塔問題 需要7步。怎麼移動大家都清楚。四個盤子的漢諾塔問題 需要15步 怎麼分析呢,把中間的看作目標柱子,把最大的移到右邊,然後就是和三個盤子的是一樣的分析了 a4 a3 a3 1.其實我們分析漢諾塔問題可以看作第n個和前n 1個兩部分,一共就三個步驟 把n 1個盤子移動到緩衝區。把第...

漢諾塔問題 c

大致題意 有a b c三個盤子用來盛餅,餅的個頭有大有小,沒有大小完全相同的,餅在盤子中必須大個的在下面,小個的放在上面。現在 a 盤中放著 n 張薄餅,需要借助 b 盤放在 c 盤中 漢諾塔問題步驟 把a,借助b,到c 1 如果只有乙個,直接a c。2 如果不止乙個,將n 1個借助c,從a b。3...

演算法 漢諾塔問題(c

演算法原理 首先把三根柱子按順序排成品字型,把所有的圓盤按從大到小的順序放在柱子a上,根據圓盤的數量確定柱子的排放順序 若n為偶數,按順時針方向依次擺放 a b c 若n為奇數,按順時針方向依次擺放 a c b。1 按順時針方向把圓盤1從現在的柱子移動到下一根柱子,即當n為偶數時,若圓盤1在柱子a,...