是回溯演算法的典型例題。
該問題是十九世紀著名的數學家高斯2023年提出:
在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊。
即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。
正確的結果應該是: 92種。
第1次考慮把皇后放在第1行的某個位置。
第2次放的時候就不用去放在第一行了,因為這樣放皇后間是可以互相攻擊的。
第2次就考慮把皇后放在第2行的某個位置,第3次考慮把皇后放在第3行的某個位置, 這樣依次去遞迴。
每計算1行,遞迴一次,每次遞迴裡面考慮8列, 即對每一行皇后有8個可能的位置可以放。
找到乙個與前面行的皇后都不會互相攻擊的位置, 然後再遞迴進入下一行。
找到一組可行解即可輸出,然後程式回溯去找下一組可靠解。
我們用乙個一維陣列來表示相應行對應的列,比如:
c[i]
=j//表示, 第i行的皇后放在第j列
一共有8列,所以我們要讓c[r]依次取第0列,第1列,第2列……
一直到第7列, 每取一次我們就去考慮,皇后放的位置會不會和前面已經放了的皇后有衝突。
怎樣是有衝突呢?同行,同列,對角線。
由於已經不會同行了,所以不用考慮這一點。
同列:
c[r]
==c[j]
;
同對角線有兩種可能,即主對角線方向和副對角線方向。
主對角線方向滿足,行之差等於列之差:
r-j==c[r]
-c[j]
;
副對角線方向滿足, 行之差等於列之差的相反數:
r-j==c[j]
-c[r];
只有滿足了當前皇后和前面所有的皇后都不會互相攻擊的時候,才能進入下一級遞迴。
#include
#include
int count =0;
intnotdanger
(int row,
int j,
int(
*chess)[8
])}// 判斷左上方
for( i=row, k=j; i>=
0&& k>=
0; i--
, k--)}
// 判斷右下方
for( i=row, k=j; i<
8&& k<
8; i++
, k++)}
// 判斷右上方
for( i=row, k=j; i>=
0&& k<
8; i--
, k++)}
// 判斷左下方
for( i=row, k=j; i<
8&& k>=
0; i++
, k--)}
if( flag1 || flag2 || flag3 || flag4 || flag5 )
else
}// 引數row: 表示起始行
// 引數n: 表示列數
// 引數(*chess)[8]: 表示指向棋盤每一行的指標
void
eightqueen
(int row,
int n,
int(
*chess)[8
])}if
(8== row )
printf
("\n");
}printf
("\n");
count++;}
else*(
*(chess2+row)
+j)=1;
eightqueen
( row+
1, n, chess2 );}
}}}int
main()
}eightqueen(0
,8, chess )
;printf
("總共有 %d 種解決方法!\n\n"
, count)
;return0;
}
def
lie(x)
: x.sort(
)if x ==
[i for i in
range(8
)]:return
true
else
:return
false
defduijiao
(x):
for i in
range(8
):for j in
range
(i+1,8
):ifabs
(x[i][0
]-x[j][0
])==abs
(x[i][1
]-x[j][1
]):return
false
else
:return
true
time =
0for a1 in
range(8
):for a2 in
range(8
):for a3 in
range(8
):for a4 in
range(8
):for a5 in
range(8
):for a6 in
range(8
):for a7 in
range(8
):for a8 in
range(8
):list1 =
[a1,a2,a3,a4,a5,a6,a7,a8]
list2 =
list
(enumerate
(list1)
)if lie(list1)
and duijiao(list2)
: qipan =[[
0for i in
range(8
)]for j in
range(8
)]for each in list2:
qipan[each[0]
][each[1]
]=1for each in qipan:
print
(each)
print
('\n'
) time +=
1print
('共有解 %d 個'
% time)
八皇后問題
八皇后問題 ackarlix 八皇后問題是乙個古老而著名的問題,是回溯演算法的典型例題。該問題是十九世紀著名的數學家高斯 1850 年提出 在 8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。高斯認為有 76種方案。1854 年在...
八皇后問題
include iostream.h int a 8 8 棋盤 int r 8 結果 int i,j int count 0 void init i j 0 int judge int x,int y for int mi x 1,mj y mi 1 mi for int ri x 1,rj y 1...
八皇后問題
package quess 由於八個皇后的任意兩個不能處在同一行,那麼這肯定是每乙個皇后佔據一行。於是我們可以定義乙個陣列columnindex 8 陣列中第i個數字表示位於第i行的皇后的列號。先把columnindex的八個數字分別用0 7初始化,接下來我們要做的事情就是對陣列columninde...