八皇后問題

2021-08-02 02:27:21 字數 2221 閱讀 4695

八皇后問題是經典的遞迴問題,題目的要求是這樣的:在西洋棋中,皇后是最強大的棋子,它可以吃掉任何跟自己同行,同列,或同一斜線上的棋子。求如何排列皇后,使得每一行都有乙個皇后又讓每乙個皇后都不能互相攻擊,給出所有的排列可能。

首先我們做一些基礎工作:

1、 用乙個二維陣列來表示棋盤,「0」代表該位置無棋子,「1」代表有皇后;

2、 我們要能夠判斷乙個位置是否能夠放置皇后(即檢測該點同行,同列或同一斜線上有無皇后);

3、 要能夠輸出乙個棋盤;

根據以上的要求,我們先編寫進行非核心段卻又必不可少的**:

(1)判斷乙個位置能否放置皇后的**:

int issafe(int (* chess)[eight], int row, int col) 

}for (i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)

}for (i = row - 1, j = col + 1; i >= 0  && j < eight; i--, j++)

}return 1;

}

從以上的**我們觀察到,僅僅是進行了三個方向的判斷,並沒有進行六個方向的判斷,這是因為我們處理八皇后問題時是逐行箱向下嘗試的,當本行沒有放置皇后時,下一行是不可能放有皇后的,只有當在本行放置了乙個皇后才能在下一行放置皇后,這就使得我們判斷乙個位置能否放置皇后時只需要考慮它的正上方,左斜上方和右斜上方。

(2)輸出棋盤

void showchess(int(*chess)[eight]) 

printf("\n");

}}

接下來我們就開始著手解決如何找出所有可能性的八皇后排列問題:

八皇后問題最關鍵的問題是如何能夠遍歷所有的情況,西洋棋的棋盤有八行八列,也就是說要嘗試8^8種情況,如果用迴圈實現的話,效果可想而知。

我們既然想要用遞迴的方式實現八皇后問題,就要找到每一次函式呼叫的普適性規律,只***每一步都是相同的操作,才能夠使用遞迴呼叫函式。通過觀察我們發現,要解決八皇后問題,每一行都應該放置且只放置乙個皇后,而每乙個位置都應該嘗試去放乙個皇后,再進行判斷這樣放置是否合理。如果乙個位置可以放置皇后了,我們又要看下一行能否放置皇后且不衝突,當判斷完該行某一位置能夠放置皇后了,就應該繼續嘗試下一行,當之後的所有行都嘗試完畢了,再進行該行的下乙個點的嘗試。

總結以上的內容可以得出這樣的結論:

1、 處理八皇后問題應該是以行為單位逐行測試的;

2、 每一行的處理都應該是相同的;

4、 當測試到第八行的時候,如果存在可以放置的皇后,則輸出當前的棋盤(當前函式的結束條件,說明找到了一種解決方案,可以進行下一種解決方案的嘗試了);

5、 當某一行測試到第八個位置的時候,依然沒有位置可以放置皇后,則放回上一行進行下乙個點的嘗試(這一點在實際程式設計中不用考慮,因為根據遞迴呼叫的性質,每一行的每乙個位置的測試都包括該行的之後所有行所有的位置的測試,測試完一整行就代表這一行以下的所有行都已經測試完畢),當然應該返回上一層進行下乙個點的測試。

例如該圖的第六行所有位置都無法放置皇后,自然第七八行也沒必要測試了,因此對於這種排列情況的測試已經完畢,需要做的就是改變第五行的皇后的位置繼續測試。

void eightqueen(int(*chess)[eight], int row) 

for (col = 0; col < eight; col++)

}}

微易碼的顏值擔當朱某人在講八皇后問題時舉了這樣乙個例子,我覺得非常有助於對遞迴的理解:在乙個很大的廣場上擺著乙個棋盤,你和其他的七個人各負責一行的測試,你自己本身就相當於是乙個八皇后的核心函式,你要做的只是從第乙個格仔開始擺放皇后,擺放之前先向上方,左斜上方和右斜上方觀察有無皇后,若有皇后則嘗試下乙個位置,放置好皇后了就通知下一行的人繼續測試有無皇后,當你測試完了所有的格仔了你要讓負責你之前一行的人繼續進行測試。當你收到負責你的下一行的人測試完畢的訊息後你也要繼續進行測試。

通過以上的比喻,可以更加清晰地看出八皇后問題的本質,以及遞迴函式在編寫時簡單卻又不容易想到的程式設計思路。

八皇后問題

八皇后問題 ackarlix 八皇后問題是乙個古老而著名的問題,是回溯演算法的典型例題。該問題是十九世紀著名的數學家高斯 1850 年提出 在 8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。高斯認為有 76種方案。1854 年在...

八皇后問題

include iostream.h int a 8 8 棋盤 int r 8 結果 int i,j int count 0 void init i j 0 int judge int x,int y for int mi x 1,mj y mi 1 mi for int ri x 1,rj y 1...

八皇后問題

package quess 由於八個皇后的任意兩個不能處在同一行,那麼這肯定是每乙個皇后佔據一行。於是我們可以定義乙個陣列columnindex 8 陣列中第i個數字表示位於第i行的皇后的列號。先把columnindex的八個數字分別用0 7初始化,接下來我們要做的事情就是對陣列columninde...