八皇后問題詳解

2021-08-17 12:08:23 字數 1902 閱讀 4464

目錄

要在8*8的西洋棋棋盤中放8個皇后,使任意兩個皇后都不能互相吃掉。規則是皇后能吃掉同一行、同一列、同一對角線的棋子。如下圖即是兩種方案:

問有多少種擺法。高斯認為有76種方案。

2023年在柏林的象棋雜誌上不同的作者發表了40種不同的解,後來有人用圖論的方法解出92種結果。

計算機發明後,有多種方法可以解決此問題。

演算法思路:

首先我們分析一下問題的解,我們每取出乙個皇后,放入一行,共有八種不同的放法,然後再放第二個皇后,同樣如果不考慮規則,還是有八種放法。於是我們可以用乙個八叉樹來描述這個過程。從根節點開始,樹每增加一層,便是多放乙個皇后,直到第8層(根節點為0層),最後得到乙個完全八叉樹。緊接著我們開始用深度優先遍歷這個八叉樹,在遍歷的過程中,進行相應的條件的判斷。以便去掉不合規則的子樹。

根據上述描述,我們可以得到如果兩個皇后q1(x1, y1)和q2(x2, y2)不符合要求,則以下四個條件之一必符合。

1 ) x1== x2(表示兩個皇后剛好在同一行)

2 ) y1=y2(表示兩個皇后不能再同一列)

3 ) x1+ y1 == x2 +y2 (斜向正方向)

4 ) x1 - y1 == x2 - y2(斜向反方向)

我們將這種思想轉換為程式思想來進行實現的話,可以使用乙個陣列a來記錄每個皇后的位置,比如a[2]=4,就意味著該皇后的位置是在(2,4)上。

某一行的皇后a[n]不能和之前的皇后a[i]位置有衝突,約束條件為:

a、不在同一列:a[n] != a[i]

b、不在同一行:因為現在是每一行求乙個皇后的位置,所以同一行不會有衝突,不需要考慮。

c、不在同一對左角線:a[n]-a[i] != n-i。 結合數學知識來看待當前這個問題,可以把它理解為斜率

舉例,a[1]=2(1,2)和a[2]=3(2,3)是在同一左對角線上的,不滿足題意。

d、不在同一右對角線:a[n]-a[i] != -(n-i)

舉例,a[1]=8和a[2]=7這兩個點在同一條直線上。

條件c和d可以合成:abs(a[n]-a[i]) != abs(n-i)

然後我們就得到了判斷位置合法性的函式

bool judge(int a,int n)

return

true;

}

現在進行模組化的程式設計思想,我們把這道題的**分為以下幾個模組兒

#include

#include

#include

#include

#include

using

namespace

std;

int n,i;//n記錄是多少個皇后的問題,i記錄的是第幾個皇后

int a[101];//陣列下標表示行號,陣列值表示列號

int sum;//記錄有多少種解法

bool judge(int a,int n) //檢測當前位置的皇后是否是合法的

return

true;

} void print_ans()

for(int j=1;j<=n;j++)

}}int main(){

cin>>n;

sum=0;

solve(1);//

cout

<

**中還是有很多不是很完善的地方,如何進行優雅的剪紙操作是乙個較大的難題。

八皇后問題

八皇后問題 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...