目錄
要在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...