八皇后問題

2021-09-30 01:50:24 字數 3309 閱讀 6262

是回溯演算法的典型例題。

該問題是十九世紀著名的數學家高斯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...