會下西洋棋的人都很清楚:皇后可以在橫、豎、斜線上不限步數地吃掉其他棋子。如何將8個皇后放在棋盤上(有8 * 8個方格),使它們誰也不能被吃掉!這就是著名的八皇后問題。 對於某個滿足要求的8皇后的擺放方法,定義乙個皇后串a與之對應,即a=b1b2…b8,其中bi為相應擺法中第i行皇后所處的列數。已經知道8皇后問題一共有92組解(即92個不同的皇后串)。給出乙個數b,要求輸出第b個串。串的比較是這樣的:皇后串x置於皇后串y之前,當且僅當將x視為整數時比y小。
輸入資料
第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數b(1 <= b <= 92)
輸出要求
n行,每行輸出對應乙個輸入。輸出應是乙個正整數,是對應於b的皇后串
輸入樣例21
92輸出樣例
15863724
84136275
分析:從n×n個格仔中選擇n個格仔擺放皇后。可見解空間樹為子集樹。
使用maze[max][max]來表示棋盤,maze[i][j]=0 表示(i,j)位置為空,maze[i][j]=1 表示(i,j)位置擺放有乙個皇后。
全域性變數way表示總共的擺放方法數目。
使用queen(t)來擺放第t個皇后。queen(t) 函式符合子集樹時的遞迴回溯正規化。當t>n時,說明所有皇后都已經擺 放完成,這是乙個可行的擺放方法,輸出結果;否則,遍歷棋盤,找皇后t所有可行的擺放位置,placequeen(i,j) 判斷皇后t能否擺放在位置(i,j)處,如果可以擺放則繼續遞迴擺放皇后t+1,如果不能擺放,則判斷下乙個位置。
placequeen(row,col)函式首先判斷位置(row,col)是否合法,繼而判斷(row,col)處是否已有皇后,有則衝突,返回0,無則繼續判斷行、列、斜方向是否衝突。斜方向分為左上角、左下角、右上角、右下角四個方向,每次從(row,col)向四個方向延伸乙個格仔,判斷是否衝突。如果所有方向都沒有衝突,則返回1,表示此位置可以擺放乙個皇后。
**:
#include#include#include# define max 4
int maze[max][max];//棋盤 0表示空白 1表示有皇后
int placequeen(int row, int col){
int i,j;
if(maze[row][row] == 1)
return 0;
for(j=0; j= 0) && (col-i >= 0))
if(maze[row-i][col-i] == 1)
return 0;
for(i=1; i= 0) && (col+i < max))
if(maze[row-i][col+i] == 1)
return 0;
for(i=1; i= 0))
if(maze[row+i][col-i] == 1)
return 0;
for(i=1; imax){//放置完成
printf("完成一次配置\n");
for(int i=0; i該問題還有更優的解法。充分利用問題隱藏的約束條件:每個皇后必然在不同的行(列),每個行(列)必然也只有乙個皇后。這樣我們就可以把n個皇后放到n個行中,使用pos[i]表示皇后i在i行中的位置(也就是列號)(i = 0 to n-1)。這樣**會大大的簡潔,因為節點的子節點數目會減少,判斷衝突也更簡單。
回溯 n皇后問題
思想 用回溯方法求解,首先要分析問題的求解空間。可用一棵n叉樹表示這個問題的求解空間,在回溯遍歷這個課二叉樹的過程中形成合理的解。對於這棵n叉樹,列序號i 0 n 1 是它的孩子,而每個孩子都有深度為n的子樹 包括自身 這些子樹的層次是n個皇后 也代表每個皇后的行序號,因為不同的皇后肯定不在同一行 ...
n皇后問題(回溯)
problem description 在n n的方格棋盤放置了n個皇后,使得它們不相互攻擊 即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。你的任務是,對於給定的n,求出有多少種合法的放置方法。input 共有若干行,每行乙個正整數n 10,表示棋盤和皇后的數量 如...
回溯經典 n皇后問題
題目大意 八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n n,而皇后個數也變成n。當且僅當 ...