八皇后問題詳細解法

2021-08-07 04:17:41 字數 1626 閱讀 4843

問題描述: 在

8×8的棋盤上,放置8個

皇后(棋子),使兩兩之

間互不攻擊。所謂互不攻擊是說任何兩個皇后都要滿足: (

1)不在棋盤的同一行; (

2)不在棋盤的同一列; (

3)不在棋盤的同一對角線上。 求:

這8個皇后中的每乙個

應該擺放在哪一列。

演算法分析: 陣列

column

、down、up

分別用來標記衝突,

column

陣列代表列衝突,從

column

[1]~

column

[8]代表第1列到第8列,如果某列上已經有皇后,則為1,否則為0;

陣列down代表主對角線衝突,為down[i-j+7](行號-列號+7),主對角線共有15條,即從b[0]~b[14],如果某條主對角線上已經有皇后,則為1,否則為0;

陣列up代表從對角線衝突,為up[i+j](行號加列號),從對角線也有15條,即從c[0]~c[14],如果某條從對角線上已經有皇后,則為1,否則為0;

其中主對角線中行i和列j相減的規律如下圖所示:

從圖中可以看出,每條主對角線上的值相同且相互之間不重複,因此可以將其看成乙個標誌進行判斷。同理,觀察次對角線中行i和列j中的值,他們相加的規律如下圖所示:

利用這一規律判斷對角線的情況。

1)需要在棋盤的( i, j ) 位置擺放乙個皇后的時候,可以通過column陣列、down陣列和up陣列的相應元素,來判斷該位置是否安全;

2)當已經在棋盤的( i, j ) 位置擺放了乙個皇后以後,就應該去修改column陣列、down陣列和up陣列的相應元素,把相應的列和對角線設定為不安全。

3)最後根據遞迴回溯的方法來實現本問題的目標。

實現函式如下:

int queen[9]=;			//第i行皇后所在的列;

int column[9]=; //第j列是否安全,

int down[15]=; //記錄每一條從上到下的對角線,是否安全,

int up[15]=; //記錄每一條從下到上的對角角線,是否安全,

int num=0; //記錄解的個數

void tryqueen(int i) // 擺放第 i 行的皇后

{ if(i<9)

{ for(int j=1;j<9;j++) // 嘗試把該皇后放在每一列

{ if(column[j]||down[i-j+7]||up[i+j-2])

continue; // 失敗

queen[i]=j; // 把該皇后放在第j列上

column[j]=1;

down[i-j+7]=1;

up[i+j-2]=1;

if(i==8) // 已找到一種解決方案

{num++;

for(int k=1;k<9;k++)

cout<

八皇后問題 遞迴求解法

include include include 八皇后問題遞迴方法實現 using namespace std ofstream file 用以計數計算結果的數目 int count 1 列印的棋盤其中列印1的位置是皇后的位置,0空位。這裡因為在控制台看不到全部,所有做了在檔案中輸出所有的解 int...

八皇后問題回溯法解法

def queen a,cur 0 if cur len a 當列遍歷到達第9列,表示乙個八皇后序列生成,結束本輪回溯 print a 列印該序列 return 0for col in range len a a cur flag col,true 初始化當前列的皇后在第0行,flag true f...

八皇后及任意多皇后問題解法之遞迴解法

遞迴解法的基本原理是把乙個大問題拆分成幾個類似的小問題,小問題繼續拆解成更小的問題,直到不能拆解的單元問題為止,再把所有單元問題的解匯集成問題的全部解。就八皇后問題而言,可以先擺第一列,共八種位置選中,每種位置選擇下,剩餘的八行七列中繼續擺放其他皇后,即變成了八個 八行七列棋盤擺七個皇后問題 的解的...