在乙個n×n的棋盤上放置n個西洋棋中的皇后,要求所有的皇后之間都不形成攻擊。請你給出所有可能的排布方案數。
輸入格式
乙個整數n
輸出格式
方案數經典的回溯題目。因為對於八皇后問題我們很難找到能夠快速得到解的方法(嗯,那些10行寫完的速度出門右拐)。所以我們採取列舉法。
皇后的攻擊特性是,同行,同列,同一對角線。那麼不妨先人為規定第k個皇后在第k行,這樣就可以根據皇后的列號求解。
我們先把第1個皇后放在第1行第一列,然後再逐行遞迴。而這個搜尋過程實際是在一棵搜尋樹上進行的
然後乙個比較關鍵的問題是如何處理對角線
就比如說這樣乙個節點,如果用x表示行,y表示列,這個節點的右對角線就可以用
x-y+n
來表示,因為在這樣一條對角線上,所以的點的橫縱座標都滿足x-y+n
我們權且把它叫做這個點的右對角線
那麼右對角線怎麼辦呢?
以這個點為例,同樣設行用x表示,列用y表示,那麼這個點的右對角線就是
x+y所以在這條對角線上的點的座標都滿足這個式子。
那麼接下來的問題就簡單了,隨便dfs,瞎標記就行了
**如下:
1 #include 2view codeusing
namespace
std;
3bool h[70], leftx[70], rightx[70];//
h表示列,即不在同一列,leftx表示左對角線,rightx表示右對角線
4int n, ans = 0;5
6 inline int
read()
13while
(isdigit(ch))
17return x *y;18}
1920
void dfs(int row)
25for(int i = 0; i < n; i++) 31}
32}33int
main()n
而在usaco上,還有一道和這個差距不是很大的題,就差了幾行**
可以看出無非就是按照上面那個思路讓在遞迴的前3層輸出所有點的列,開乙個陣列記錄一下列就好了
dfs**如下:
回溯 八皇后問題
八皇后問題 國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。分析 八皇后問題是回溯演算法的典型案例。我想我們在自己做的過程中,是這樣的 是先從 0,0 這個座標開始排放皇后,然後 1...
八皇后問題 回溯
在劉汝佳老師的書中對於8皇后問題的分析 我感覺非常經典 8皇后問題可行的解 92個 一共有3種思考的出發點 從64個格仔中選乙個子集,使得 子集中恰好有8個格仔,且任意兩個選出的格仔都不在同一行,同一列或同一對角線上 這正是子集的列舉問題。然而,64個格仔的子集有264個,太大了,這並不是乙個很好的...
八皇后問題(回溯)
八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。可設定乙個陣列a i j,代表第i行第j列放置棋子。先按行從上往下的順序,每遞迴一次,在每一行的某一列放乙個棋...