回溯 八皇后問題(蒟蒻)

2022-07-13 03:51:11 字數 1458 閱讀 9798

在乙個n×n的棋盤上放置n個西洋棋中的皇后,要求所有的皇后之間都不形成攻擊。請你給出所有可能的排布方案數。

輸入格式

乙個整數n

輸出格式

方案數經典的回溯題目。因為對於八皇后問題我們很難找到能夠快速得到解的方法(嗯,那些10行寫完的速度出門右拐)。所以我們採取列舉法。

皇后的攻擊特性是,同行,同列,同一對角線。那麼不妨先人為規定第k個皇后在第k行,這樣就可以根據皇后的列號求解。

我們先把第1個皇后放在第1行第一列,然後再逐行遞迴。而這個搜尋過程實際是在一棵搜尋樹上進行的

然後乙個比較關鍵的問題是如何處理對角線

就比如說這樣乙個節點,如果用x表示行,y表示列,這個節點的右對角線就可以用

x-y+n

來表示,因為在這樣一條對角線上,所以的點的橫縱座標都滿足x-y+n

我們權且把它叫做這個點的右對角線

那麼右對角線怎麼辦呢?

以這個點為例,同樣設行用x表示,列用y表示,那麼這個點的右對角線就是

x+y所以在這條對角線上的點的座標都滿足這個式子。

那麼接下來的問題就簡單了,隨便dfs,瞎標記就行了

**如下:

1 #include 2

using

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

view code

而在usaco上,還有一道和這個差距不是很大的題,就差了幾行**

可以看出無非就是按照上面那個思路讓在遞迴的前3層輸出所有點的列,開乙個陣列記錄一下列就好了

dfs**如下:

回溯 八皇后問題

八皇后問題 國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。分析 八皇后問題是回溯演算法的典型案例。我想我們在自己做的過程中,是這樣的 是先從 0,0 這個座標開始排放皇后,然後 1...

八皇后問題 回溯

在劉汝佳老師的書中對於8皇后問題的分析 我感覺非常經典 8皇后問題可行的解 92個 一共有3種思考的出發點 從64個格仔中選乙個子集,使得 子集中恰好有8個格仔,且任意兩個選出的格仔都不在同一行,同一列或同一對角線上 這正是子集的列舉問題。然而,64個格仔的子集有264個,太大了,這並不是乙個很好的...

八皇后問題(回溯)

八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。可設定乙個陣列a i j,代表第i行第j列放置棋子。先按行從上往下的順序,每遞迴一次,在每一行的某一列放乙個棋...