由於我水平有限,本文參考了網上的各個做法,選取了我最能理解的解法,我盡量地解釋這個解法來檢驗我對本問題的理解程度(只寫出最終的解法數量)。
八皇後問題講的是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位皇後都確定。這種取消了錯誤條件繼續運行步驟的方法,大大減少了運行時間。
相同方法的還有迷宮問題。