當前位置:首頁 > 芯聞號 > 充電吧
[導讀]1.河內之塔說明:河內之塔(Towers of Hanoi)是法國人M.Claus(Lucas)于1883年從泰國帶至法國的,河內為越戰(zhàn)時北越的首都,即現(xiàn)在的胡志明市;1883年法國數(shù)學家 Edoua

1.河內之塔

說明:河內之塔(Towers of Hanoi)是法國人M.Claus(Lucas)于1883年從泰國帶至法國的,河內為越戰(zhàn)時北越的首都,即現(xiàn)在的胡志明市;1883年法國數(shù)學家 EdouardLucas曾提及這個故事,據(jù)說創(chuàng)世紀時Benares有一座波羅教塔,是由三支鉆石棒(Pag)所支撐,開始時神在第一根棒上放置64個由上至下依由小至大排列的金盤(Disc),并命令僧侶將所有的金盤從第一根石棒移至第三根石棒,且搬運過程中遵守大盤子在小盤子之下的原則,若每日僅搬一個盤子,則當盤子全數(shù)搬運完畢之時,此塔將毀損,而也就是世界末日來臨之時。

解法:如果柱子標為ABC,要由A搬至C,在只有一個盤子時,就將它直接搬至C,當有兩個盤子,就將B當作輔助柱。如果盤數(shù)超過2個,將第三個以下的盤子遮起來,就很簡單了,每次處理兩個盤子,也就是:A->B、A ->C、B->C這三個步驟,而被遮住的部份,其實就是進入程式的遞回處理。事實上,若有n個盤子,則移動完畢所需之次數(shù)為2^n- 1,所以當盤數(shù)為64時,則所需次數(shù)為:264- 1 = 18446744073709551615為5.05390248594782e+16年,也就是約5000世紀,如果對這數(shù)字沒什幺概念,就假設每秒鐘搬一個盤子好了,也要約5850億年左右。


#include


void hanoi(intn, char A, char B, char C) {

if(n == 1) {

printf("Move sheet %d from %c to%cn", n, A, C);

}

else {

hanoi(n-1, A, C, B);

printf("Move sheet %d from %c to%cn", n, A, C);

hanoi(n-1, B, A, C);

}

}


int main() {

int n;

printf("請輸入盤數(shù):");

scanf("%d", &n);

hanoi(n, 'A', 'B', 'C');

return 0;

}

2.AlgorithmGossip: 費式數(shù)列

說明:Fibonacci為1200年代的歐洲數(shù)學家,在他的著作中曾經(jīng)提到:「若有一只免子每個月生一只小免子,一個月后小免子也開始生產(chǎn)。起初只有一只免子,一個月后就有兩只免子,二個月后有三只免子,三個月后有五只免子(小免子投入生產(chǎn))......。

如果不太理解這個例子的話,舉個圖就知道了,注意新生的小免子需一個月成長期才會投入生產(chǎn),類似的道理也可以用于植物的生長,這就是Fibonacci數(shù)列,一般習慣稱之為費氏數(shù)列,例如以下: 1、1 、2、3、5、8、13、21、34、55、89......

解法:依說明,我們可以將費氏數(shù)列定義為以下:

fn = fn-1 + fn-2   if n> 1

fn = n       if n = 0, 1

#include

#include


#define N 20


int main(void) {

int Fib[N] ={0};

int i;


Fib[0] = 0;

Fib[1] = 1;


for(i = 2; i< N; i++)

Fib[i] =Fib[i-1] + Fib[i-2];


for(i = 0; i< N; i++)

printf("%d", Fib[i]);

printf("n");


return 0;

}

3. 巴斯卡三角形


#include

#define N 12

long combi(intn, int r){

int i;

long p = 1;

for(i = 1; i <= r; i++)

p = p * (n-i+1) / i;

return p;

}

void paint() {

int n, r, t;

for(n = 0; n <= N; n++) {

for(r = 0; r <= n; r++) {

int i;/* 排版設定開始 */

if(r == 0) {

for(i = 0; i <= (N-n); i++)

printf(" ");

}else {

printf(" ");

} /* 排版設定結束 */

printf("%3d", combi(n,r));

}

printf("n");

}

}

4.AlgorithmGossip: 三色棋

說明:三色旗的問題最早由E.W.Dijkstra所提出,他所使用的用語為Dutch Nation Flag(Dijkstra為荷蘭人),而多數(shù)的作者則使用Three-ColorFlag來稱之。


假設有一條繩子,上面有紅、白、藍三種顏色的旗子,起初繩子上的旗子顏色并沒有順序,您希望將之分類,并排列為藍、白、紅的順序,要如何移動次數(shù)才會最少,注意您只能在繩子上進行這個動作,而且一次只能調換兩個旗子。

解法:在一條繩子上移動,在程式中也就意味只能使用一個陣列,而不使用其它的陣列來作輔助,問題的解法很簡單,您可以自己想像一下在移動旗子,從繩子開頭進行,遇到藍色往前移,遇到白色留在中間,遇到紅色往后移,如下所示:

只是要讓移動次數(shù)最少的話,就要有些技巧:

如果圖中W所在的位置為白色,則W+1,表示未處理的部份移至至白色群組。

如果W部份為藍色,則B與W的元素對調,而B與W必須各+1,表示兩個群組都多了一個元素。

如果W所在的位置是紅色,則將W與R交換,但R要減1,表示未處理的部份減1。


注意:B、W、R并不是三色旗的個數(shù),它們只是一個移動的指標;什幺時候移動結束呢?一開始時未處理的R指標會是等于旗子的總數(shù),當R的索引數(shù)減至少于W的索引數(shù)時,表示接下來的旗子就都是紅色了,此時就可以結束移動,如下所示:


#include

#include

#include


#define BLUE 'b'

#define WHITE'w'

#define RED 'r'


#define SWAP(x,y) { char temp;

temp = color[x];

color[x] = color[y];

color[y] = temp; }


int main() {

char color[] = {'r', 'w', 'b', 'w', 'w',

'b', 'r', 'b', 'w', 'r','