8皇后問題:如何在
8 x 8
的西洋棋棋盤上安排
8個皇后,使得沒有兩個皇后能互相攻擊?
( 如果兩個皇后處在同一行、同一列或同一條對角線上,則她們能互相攻擊。)
解向量為長度為8
的陣列,記為
solution
。因為共有
8個皇后,而棋盤剛好為
8*8,所以每一行肯定會有乙個皇后,那麼我們約定
solution[i]
表示第i+1
個皇后放在第
i+1行的第幾列。
solution
中的列從
1開始記。
遞迴版本:
void eight_queue_recursive( int *solution, int dimension, int row )
solution[row-1] = 0;
}}
一般的回溯演算法可以描述如下:
backtrack(k)
for 每個x∈xk
if x is valid
xk←x;將xk加入v
if v 為最終解then print the solution
else if v 是部分解then backtrack(k+1)
end for
迭代版本:
void eight_queue( int *solution, int dimension )
}
solution[k] = 0;//回溯
--k;
}
}
在判斷某個位置是否可以放皇后時,需要注意如下規律:
1.從左上角到右下角的主對角線或其平行線(斜率-1)上,下標之差(行號-列號)相
等。2.斜率為+1的斜線上,元素的2個下標之和(行號+列號)值相等。
即若兩個皇后的位置分別為(i,j)和(k,l),且i-j=k-l 或 i+j = k+l,那麼這兩個皇后位於一條斜線上。上面兩個方程又和轉化為i-k = j-l 和 i-k = l-j
即只要|i-k| = |l-j|,那麼這兩個皇后在一條斜線上,位置衝突.運用上面的規律,if_valid會大大簡化。
今天上午寫了非遞迴的,執行的時候竟然有幾千個解,很納悶,而且是重複著輸出。除錯了半天,原來是最外層的while迴圈條件應該是k>=0,最初寫成了 k上面的程式同樣適用於n皇后問題,試了一下,把8換成18後,程式竟然可以得到幾十萬個解,當然程式沒跑完我就給停了。
八皇后問題 回溯 遞迴 回溯 非遞迴
八皇后問題 在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。分析 我們可以嘗試在將第乙個皇后擺放在第0行第0列,為了不衝突,將第二個皇后擺放在第1行第3列 依次下去 然後發現第5行每個位置都有衝突,這說明上面4行肯定不能這麼擺放...
回溯法 八皇后問題(非遞迴)
回溯法 試探法 八皇后問題 非遞迴 列印一組解 includeint col 8 int left 15 int right 15 int q 8 void queen void if j 8 int main else printf n return 0 n皇后問題 列印第一組解 include ...
八皇后問題遞迴和非遞迴演算法
大名鼎鼎的八皇后問題。相信大家都耳熟能詳。八皇后的是乙個典型的用回溯法求解的問題。在回溯法中的乙個關鍵是要動態儲存求解空間對應的程式所處的狀態,特別是能夠進行狀態 回滾 當一發現個部分解再往下去不能成為合法的解時,要回溯到這個部分解之前所處的狀態。程式狀態的 前進 和 回滾 用ban和unban函式...