軟體課講了這些問題,這次順便總結下。
說白了也就是:遞迴,回溯,深搜或者廣搜。
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,...