python3 回溯法解決八皇后問題 詳細解釋

2021-10-02 06:43:01 字數 1787 閱讀 8437

問題:西洋棋棋盤是8 * 8的方格,每個方格裡放乙個棋子。皇后這種棋子可以攻擊同一行或者同一列或者斜線(左上左下右上右下四個方向)上的棋子。在乙個棋盤上如果要放八個皇后,使得她們互相之間不能攻擊(即任意兩兩之間都不同行不同列不同斜線),求出一種(進一步的,所有)布局方式。

思路:(貼上一波網上已有的遞迴思路,就不碼字了)第乙個需要解決的小問題就是,如何用數學的語言來表述斜線上重疊的皇后。其實我們可以看到,對於位於(i,j)位置的皇后而言,其四個方向斜線上的格仔下標分別是 (i-n,j+n), (i-n,j-n), (i+n,j-n), (i+n,j+n)。當然i和j的±n都要在[0,7]的範圍內,保持不越界。暫時拋開越界限制不管,這個關係其實就是:目標格仔(a,b)和本格仔(i,j)在同一條斜線上 等價於 |a - i| == |b - j|

然後,從遞迴的思想來看,我們在從第一行開始給每一行的皇后確定乙個位置。每來到新的一行時,對本行的所有可能位置(皇后放在這個位置和前面所有已放置的皇后無衝突)分別進行遞迴地深入;若某一行可能的位置數為0,則表明這是一條死路,返回上一層遞迴尋找其他辦法;若來到的這一行是第九行(不存在第九行,只不過是說明前八行都已經正確配置,已經得到乙個解決方案),這說明得到解決方案。

可以看到,尋找一行內皇后應該擺放的位置這是個遞迴過程,並且在進入遞迴時,應該要告訴這個過程的東西包括兩個:1. 之前皇后放置的狀態, 2. 現在是第幾行。

現在上**:

def queen

(a, cur=0)

:if cur ==

len(a)

:for i in a:

print

(' - '

* i,

'q',

' - '*(

7- i)

) # 格式化輸出

print

('='*23

)return

for col in range

(len

(a))

: a[cur]

= col # 儲存當前皇后所在的位置:cur是當前皇后的行號,col是當前皇后的列號

no_coflict = true # 假設兩個皇后之間不存在衝突

#判斷當前皇后與之前所有的恍惚是否存在衝突

for index in range

(cur)

: # 上index個皇后:index是上個恍惚的行號,a[index]是上個皇后的列號

if a[index]

== col: # 判斷是否同列

no_coflict = false

break

# 判斷兩個皇后是否同斜線等價於兩個皇后橫座標之差的絕對值是否與縱座標的絕對值之差相等|x-xn|

==|y-yn|

row =

abs(cur - index)

column =

abs(col - a[index]

)if row == column: # 判斷是否同斜線

no_coflict = false

break

if no_coflict: # 兩個皇后位置不存在衝突,則繼續找下乙個皇后的位置

queen

(a, cur +1)

queen([

0]*8

)

推薦乙個用動畫學習演算法的**,通過動畫深入理解遞迴的執行過程(這個專案已經提供了好多種演算法的**了,包括:暴力、動態規劃、回溯、分治、貪心等多種型別演算法):

九度 1140 回溯 八皇后

會下西洋棋的人都很清楚 皇后可以在橫 豎 斜線上不限步數地吃掉其他棋子。如何將8個皇后放在棋盤上 有8 8個方格 使它們誰也不能被吃掉!這就是著名的八皇后問題。乙個皇后q x,y 能被滿足以下條件的皇后q row,col 吃掉 x row 在縱向不能有兩個皇后 y col 橫向 col row y ...

006回溯法 n皇后問題

在n n格的棋盤上放置彼此不受攻擊的n個皇后。按照西洋棋的規則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。n後問題等價於在n n格的棋盤上放置n個皇后,任何2個皇后不放在同一行或同一列或同一斜線上。如下 nqueen by xcz on 2013.9.10 include include...

N皇后問題 12 回溯法 簡單

回溯法,主要應用在dfs中,主要思想是當你push乙個元素後,記住要pop回去,大致的模板是 path.push back nums i dfs pos 1 path.pop 詳細的模板在我們之前用回溯法解決全排列問題有提到。n 皇后問題研究的是如何將 n 個皇后放置在 n n 的棋盤上,並且使皇后...