————— 次日 —————程序員
題目是什麼意思呢?算法
國際象棋中的皇后,能夠橫向、縱向、斜向移動。如何在一個8X8的棋盤上放置8個皇后,使得任意兩個皇后都不在同一條橫線、豎線、斜線方向上?數組
讓咱們來舉個栗子,下圖的綠色格子是一個皇后在棋盤上的「封鎖範圍」,其餘皇后不得放置在這些格子:函數
下圖的綠色格子是兩個皇后在棋盤上的「封鎖範圍」,其餘皇后不得放置在這些格子:3d
那麼,如何遵循規則,同時放置這8個皇后呢?讓咱們來看看小灰的回答。cdn
————————————blog
什麼是八皇后問題?遞歸
八皇后問題是一個古老的問題,於1848年由一位國際象棋棋手提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,如何求解?數學
以高斯爲表明的許多數學家前後研究過這個問題。後來,當計算機問世,經過計算機程序的運算能夠輕鬆解出這個問題。it
如何解決八皇后問題?
所謂遞歸回溯,本質上是一種枚舉法。這種方法從棋盤的第一行開始嘗試擺放第一個皇后,擺放成功後,遞歸一層,再遵循規則在棋盤第二行來擺放第二個皇后。若是當前位置沒法擺放,則向右移動一格再次嘗試,若是擺放成功,則繼續遞歸一層,擺放第三個皇后......
若是某一層看遍了全部格子,都沒法成功擺放,則回溯到上一個皇后,讓上一個皇后右移一格,再進行遞歸。若是八個皇后都擺放完畢且符合規則,那麼就獲得了其中一種正確的解法。
提及來有些抽象,咱們來看一看遞歸回溯的詳細過程。
1.第一層遞歸,嘗試在第一行擺放第一個皇后:
2.第二層遞歸,嘗試在第二行擺放第二個皇后(前兩格被第一個皇后封鎖,只能落在第三格):
3.第三層遞歸,嘗試在第三行擺放第三個皇后(前四格被第一第二個皇后封鎖,只能落在第五格):
4.第四層遞歸,嘗試在第四行擺放第四個皇后(第一格被第二個皇后封鎖,只能落在第二格):
5.第五層遞歸,嘗試在第五行擺放第五個皇后(前三格被前面的皇后封鎖,只能落在第四格):
6.因爲全部格子都「綠了」,第六行已經沒辦法擺放皇后,因而進行回溯,從新擺放第五個皇后到第八格。:
7.第六行仍然沒有辦法擺放皇后,第五行也已經嘗試遍了,因而回溯到第四行,從新擺放第四個皇后到第七格。:
8.繼續擺放第五個皇后,以此類推......
八皇后問題的代碼實現?
解決八皇后問題,能夠分爲兩個層面:
1.找出第一種正確擺放方式,也就是深度優先遍歷。
2.找出所有的正確擺放方式,也就是廣度優先遍歷。
因爲篇幅優先,咱們本篇只介紹如何找出第一種正確擺放方式。
在研究代碼實現的時候,咱們須要解決幾個問題:
1.國際象棋的棋盤如何表示?
很簡單,用一個長度是8的二維數組來表示便可。
因爲這裏使用的是int數組,int的初始值是0,表明沒有落子。當有皇后放置的時候,對應的元素值改成1。
在這裏,二維數組的第一個維度表明橫座標,第二個維度表明縱座標,而且從0開始。好比chessBoard[3][4]表明的是棋盤第四行第五列格子的狀態。
2.如何判斷皇后的落點是否合規?
定義一個check方法,傳入新皇后的落點,經過縱向和斜向是否存在其餘皇后來判斷是否合規。
3.如何進行遞歸回溯?
遞歸回溯是本算法的核心,代碼邏輯有些複雜
4.如何輸出結果?
這個問題很簡單,直接遍歷二維數組並輸出就能夠。
5.如何把這些方法串起來?
在main函數裏分三步來調用:
第一步:初始化
第二步:遞歸擺放皇后
第三步:最後輸出結果。
其中Queen8是整個類的名字。
最終輸出以下:
10000000
00001000
00000001
00000100
00100000
00000010
01000000
00010000
幾點補充:
1.因爲篇幅緣由,這一篇只講瞭如何找出第一種正確的八皇后擺放。你們若是有興趣,能夠對文中的代碼稍做改動,實現找出全部八皇后擺放的代碼。
2.本漫畫純屬娛樂,還請你們儘可能珍惜當下的工做,切勿模仿小灰的行爲哦。
—————END—————
喜歡本文的朋友們,歡迎長按下圖關注訂閱號程序員小灰,收看更多精彩內容