史上最簡明八皇后問題分析與套路總結

2021-10-21 11:47:05 字數 1913 閱讀 3695

八皇后問題是乙個以西洋棋為背景的問題:如何能夠在8×8的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題:這時棋盤的大小變為n×n,而皇后個數也變成n。當且僅當n = 1或n ≥ 4時問題有解。(問題描述來自參考文獻1)

數學王子高斯當年花費了無數心血,最後計算認為八皇后問題有76種解法,現在我們通過計算機模擬可以輕鬆計算出八皇后問題的真正解法有92種。能讓高斯栽跟頭的問題,可想而知計算的複雜性與難度。

高斯將八皇后的解法推導出76種,已經算是非常厲害了。這不能怨高斯,而是八皇后的計算複雜度確實太高。

該問題的整體思路還是暴力解法

1.先列出所有可能的皇后擺放方式。

2.再檢查該種擺放方式是否符合要求。

具體的執行過程如下:

先將第乙個皇后放在第一行第一列,然後將第二個皇后放在第二行第一列,判斷該種擺法是否符合要求。很明顯這樣擺不行,有兩個皇后會在同一列。再將第二個皇后放在第二行第二列,這樣也不行,兩個皇后會在一條斜線上。將第二個皇后放在第二行第三列,這樣滿足當前條件。

目前已經有兩個皇后滿足條件,接下來放第三個,還是從第三行第一列開始放置,不滿足條件再放第二列,第三列…一直到第8個皇后也能放在乙個不衝突的位置,此時找到乙個符合要求的解。

然後我們開始回溯,將第乙個皇后放在第一行第二列,後面的就繼續按上面的方式迴圈,一直到回溯完畢,找出所有符合條件的解為止。

參考文獻2有張圖,比較詳細的用圖描述了上面的過程,貼出來大家參考。下面圖描述的是4皇后的回溯過程,原理跟8皇后是一致的。

上面原理分析完畢,接下來看**實現。

public class nqueuev2 

}for(int m=row-1, n=column+1; m>=0 && n**輸出結果:

0 1 0 0

0 0 0 1

1 0 0 0

0 0 1 0

0 0 1 0

1 0 0 0

0 0 0 1

0 1 0 0

result is: 2

上面的**,為了方便輸出最後結果,模擬的是4皇后,8皇后只需要將n改為8即可。

board二維陣列,模擬的是棋盤,初始狀態均為0,表示該位置沒有放置皇后。如果該位置設為1,表明該位置有皇后。

k表示放置的皇后個數。如果k==n,說明n個皇后都被放置完畢,此時得到乙個有效解。

for(int row=0; row該部分**輸出有效解的狀態,陣列為1的位置表示該位置放置了皇后。

else部分**,i表示的是第i列,check(k, i)方法表示的是在(k, i)這個位置放置皇后是否合法

for(int i=0; i這部分**,表示兩個皇后不能放置在同一列。

for(int m=row-1, n=column-1; m>=0 && n >= 0; m--, n--)

}

這部分**,表示該皇后的左斜線部分不能有皇后。

for(int m=row-1, n=column+1; m>=0 && n這部分**,表示該皇后的右斜線部分不能有皇后。

如果該位置能放置皇后,則將棋盤中該位置置為1,接下來往下一行放皇后putqueque(k+1)。同時,在回溯的時候,需要將該位置置為0。

所以看上去很複雜的八皇后問題,對著圖,再對著**分析,是不是感覺沒那麼難了?

本質還是經典回溯演算法的使用,跟前面我們講到的排列組合類似。當了解完整個過程以後,回溯的難度甚至比排列組合還小!

史上最全排列組合演算法詳解以及套路總結一文搞定

1.2.

n皇后問題與八皇后

這裡的n皇后問題指在乙個nxn的棋盤上放置n個棋子,使得每行每列和每條對角線上都只有乙個棋子,求其擺放的方法數。當且僅當n 1 或 n 4 時問題有解。class queens vector vector res int result 0 bool test int cur for int i 0 ...

八皇后問題詳細思路分析

static int count 0 共多少解法 public static void main string args 編寫乙個方法,放置第n個皇后 特別主意 check 是每一次遞迴時,進入到check中都有for int i 0 i private void check int n 如果沒有到...

八皇后問題的簡單分析

八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后。為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。基本思路 將棋盤分為8行,每一行填充乙個棋子,這樣就能保證每一行不衝突,具體到每一行的話,又分為8種可能,顯然...