由於我水平有限,本文參考了網上的各個做法,選取了我最能理解的解法,我盡量地解釋這個解法來檢驗我對本問題的理解程度(只寫出最終的解法數量)。
八皇後問題講的是8個皇後棋在一個8*8的棋盤上,誰都不能攻擊到對方,皇後的攻擊方向有橫豎斜三個方向,不同的擺放形成不同的解法。
其實就是一個給皇後找位置的游戲,先確定第一個皇後的位置,剩下的逐行根據規則確定,成功的輸出,失敗的返回上一個位置試下一個位置,直到8個皇後全部選好位置。
以下是具體的代碼(java)
1 //8皇後問題 2 public class Queen 3 { 4 private int[] column; //同列是否有皇後,1表示有,0表示沒有 5 private int[] rsl; //右上至左下是否有皇後 6 private int[] lsl; //左上至右下是否有皇後 7 private int[] queen; //皇後編號 8 private static int num;//答案數量 9 public Queen() 10 { 11 column=new int[9]; 12 rsl=new int[17]; 13 lsl=new int[17]; 14 for(int i=1;i<=8;i++) 15 { 16 column[i]=0; //初始定義全部無皇後 17 } 18 for(int i=1;i<=16;i++) 19 { 20 rsl[i]=lsl[i]=0; 21 } 22 queen=new int[9]; 23 } 24 public void backtrack(int i) //這裡的i才是行數 25 { 26 if(i>8) 27 { 28 num++; //最後大於8表示8個皇後都找到了位置,解答數加一 29 } 30 else 31 { 32 for(int j=1;j<=8;j++) 33 { 34 if((column[j]==0)&&(rsl[i+j]==0)&&(lsl[i-j+8]==0))//判斷橫豎斜有沒有皇後 35 { 36 queen[i]=j;//皇後位置 37 column[j]=rsl[i+j]=lsl[i-j+8]=1;//設定為占用 38 backtrack(i+1); //循環調用 39 column[j]=rsl[i+j]=lsl[i-j+8]=0;//再定義無皇後 40 } 41 } 42 } 43 } 44 public static void main(String[]args) 45 { 46 Queen queen=new Queen(); 47 queen.backtrack(1);//開始回溯法,從行1開始 48 System.out.println("\n解答數為"+num); //輸出總解答數 49 } 50 }
所謂回溯就是不停的嘗試,遇到錯誤答案時,直接放棄錯誤條件,回到上一步改變條件繼續。上面的代碼中,在確定了第一行第一個皇後位置後,將能攻擊的位置都標示出來,再調用函數嘗試第二行也就是第二個皇後的位置,滿足條件就繼續第三個,不滿足就調用結束,初始化條件,同理直到8位皇後都確定。這種取消了錯誤條件繼續運行步驟的方法,大大減少了運行時間。
相同方法的還有迷宮問題。