八皇后問題

2021-10-17 04:20:24 字數 1970 閱讀 7597

【8-8】皇后是西洋棋中威力最大的棋子,在下面所示的棋盤上,皇后可以攻擊位於箭頭所覆蓋位置的所有棋子。

我們能不能把8個皇后放在棋盤上,它們中任何乙個都無法攻擊其餘的皇后?這個問題被稱為八皇后問題,你的任務是編寫乙個程式,找到八皇后問題的所有答案,看看一共有多少種答案。

這個題目是對回溯法的考察,難度5顆星,各大刷題**和面試**現經常出現,所以必須掌握。題目也給出了基本的演算法思路。

回溯法(探索與回溯法)是一種選優搜尋法,又稱為試探法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為「回溯點」。

這裡先把規則理出來: 皇后不能同列,不能同行,不能在對角線上。

首先把皇后放在第一行第一列,然後遍歷這個皇后固定在第一行第一列後的所有解;

然後再將第一行第一列的那個皇后固定在第一行第二列,再次遍歷完所有解;

直到 第一行的皇后放在最後一列,遍歷完所有的解。

第一行不需要校驗上半部分的衝突,所以直接放置。

固定皇后在[0][0]位置:

判斷第1行哪些列可以放置皇后,放置皇后

判斷第2行哪些列可以放置皇后,放置皇后

判斷第3行哪些列可以放置皇后,放置皇后

判斷第4行哪些列可以放置皇后,放置皇后

判斷第5行哪些列可以放置皇后,放置皇后

判斷第6行哪些列可以放置皇后,放置皇后

判斷第7行哪些列可以放置皇后,放置皇后

其他地依次類推

所以這個邏輯就可以描述為:

for(column = 0; column < 8; column++) 

//有衝突無法放置

board[row][column] = false;

}

可以看到這裡有乙個繼續向下放置皇后,每一行放置後就需要繼續放置下一行的皇后,而且放置邏輯都是一樣,只是行數不一樣,所以很容易就可以想到遞迴。

void place_queen(int row) 

//有衝突無法放置

board[row][column] = false;

}}

判斷衝突抽象為乙個函式:

判斷當前校驗的位置的同列上面有無放置皇后,

判斷同行左側和右側有無放置皇后,

判斷左上部分和右上部分的對角線有無放置皇后

所以這個衝突檢測行數可以抽象為:

//檢測board[row][column]的上半部分的方向上是否有其他皇后

int conflicts(int row, int column)

return 0;

}

完整**如下:

#define true 1

#define false 0

int board[8][8];

//列印解決方案

void print_board()

putchar('\n');

}putchar('\n');

}//檢測board[row][column]的上半部分的方向上是否有其他皇后

int conflicts(int row, int column)

return 0;

}//回溯法呼叫自身

void place_queen(int row)

}int main()

這個題目考察遞迴,遞迴屬於很抽象的邏輯,但是在程式演算法中很重要,所以對遞迴的理解運用很重要。

八皇后問題

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