八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於2023年提出:在8×8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。n皇后問題是由8皇后拓展而來,其本質還是8皇后問題,主要思路是通過不斷遞迴擺放棋子來減少可以擺放棋子的宮格,最終找到解。
先從簡單的 4*4 宮格來討論:
初始化 4*4 棋盤,0表示沒有棋子,1表示放置了棋子,小於0表示不能放置棋子(路障)
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
從第一行第乙個開始遍歷,放置乙個棋子然後在橫豎斜對角放置路障
1-1 -1 -1
-1 -1 0 0
-1 0 -1 0
-1 0 0 -1
接著遞迴進入第二行,發現有為0的的宮格表示可以放置棋子,繼續放置棋子
1 -1 -1 -1
-1 -11-1
-1 -1 -1 -1
-1 0 -1 -1
此時繼續遞迴進入第三行,發現已經不能放置棋子了,接著返回第二行重新放置棋子。
1 -1 -1 -1
-1 -1 -11
-1 0 -1 -1
-1 -1 0 -1
此時繼續遞迴進入第三行放置棋子,直到最後一行可以放置棋子則表示這種布局有解。
實現細節:
1.因為每次都是按行向下遞迴,所以不用在棋子所在行和上方放置路障
2.如果想恢復上一次遞迴的狀態不能直接設定值,例如:
1-1 -1
-1 -11
-1 -1 -1
此時已經遞迴到第二行,第三行不可放置棋子如果恢復到第二行放置之前的狀態,將第二行的棋子和路障去掉會變成:
1-1 -1
-1 -1 0
-1 0 0
這時我們同時把第一行棋子的路障去掉了,所以不正確,解決辦法是用增量而不是固定值,每設定一次棋子都+1,路障對應的位置都-1:
1-1 -1
-1 -11
-1 -1 -2
此時還原的時候棋子-1,路障+1即可:
1-1 -1
-1 -1 0
-1 0 -1
go語言實現
package main
import
("fmt"
)const n int=8
var board [n]
[n]int
=[n]
[n]int
}//初始化棋盤
var result int=0
func
setblock
(row int
, col int
, val int
)for r := row; r < n; r++
for r, c := row, col; r < n && c < n;
}func
recursive
(row int
, col int
)for
; col < n; col++}}
func
main()
n
解的個數11
2030
42510
64740
8929352
10724
112680
1214200
1373712
14365596
152279184
1614772512
1795815104
18666090624
194968057848
2039029188884
N皇后問題 c語言實現
問題描述 有乙個n n的棋盤,在這個棋盤中放n個皇后,使得這n個皇后,任意兩個皇后不在同一行,同一列,同一條對角線。例如,當n等於4時,有兩種擺法。輸入只有乙個整數n。思路如果我們是從這個n n的棋盤中選取n個方格放皇后,再去判斷是否滿足條件的話,則效率會非常低,這是乙個組合數 complement...
基於C語言實現的N皇后問題
1 專案簡介 八皇后問題是乙個古老而著名的問題,是回溯演算法的經典問題。該問題是十九世紀著名的數學家高斯在1850年提出的 在8 8的西洋棋棋盤上,安放8個皇后,要求沒有乙個皇后能夠 吃掉 任何其它乙個皇后,即任意兩個皇后不能處於同一行,同一列或者同一條對角線上,求解有多少種擺法。高斯認為有76種方...
基於C語言實現的N皇后問題
1 專案簡介 八皇后問題是乙個古老而著名的問題,是回溯演算法的經典問題。該問題是十九世紀著名的數學家高斯在1850年提出的 在8 8的西洋棋棋盤上,安放8個皇后,要求沒有乙個皇后能夠 吃掉 任何其它乙個皇后,即任意兩個皇后不能處於同一行,同一列或者同一條對角線上,求解有多少種擺法。高斯認為有76種方...