1. 程式人生 > >回溯法解決N皇后問題(java實現)

回溯法解決N皇后問題(java實現)

1.簡單介紹回溯法思路,就是將所有的結果變成一棵樹,從樹的結點開始訪問,採用深度優先策略,從樹的根結點開始訪問,如果滿足條件,繼續訪問下一層,如果不滿足條件,返回上一個結點,繼續訪問其它結點。重複操作。
2. 對於N皇后問題,我特意做了一張圖片。首先放置第一列,有四种放法,如果第一列,放置在第一個,再放置第二列,也有四种放法,很顯然,第二列的第一種放法,不符合條件,這種放法下面所的子樹也就不必訪問了,節省了訪問時間,然後繼續第三列,第四列。就可以得到結果了。
這裡寫圖片描述
3.這裡的程式碼是參考網上的,不記得是部落格地址是哪了,不好意思。原始碼是用C語言實現的,我改成了java。參考如下

package com.bc;

public
class huanghou { public static int Q=4; //代表四皇后 public static void main(String[] args) { // TODO Auto-generated method stub int[][] dp=new int[Q][Q]; int i,j; //初始化 for(i=0;i<Q;i++) { for(j=0;j<Q;j++) { dp[i][j]=0
; } } que(0,dp); } private static void que(int m, int[][] dp) { // TODO Auto-generated method stub if(m==Q){//遞迴結束條件 for(int i=0;i<Q;i++) { for(int j=0;j<Q;j++) { System.out.print(dp[i][j]+" "
); } System.out.println("\n"); } System.out.println("**********************"); } //遞迴計算 for(int i=0;i<Q;i++) { if (isCorrt(i,m,dp)) { dp[i][m]=1; que(m+1, dp); dp[i][m]=0; } } } //判斷這個位置能不能放皇后 private static boolean isCorrt(int i, int j, int[][] dp) { // TODO Auto-generated method stub int s, t; //s代表行,t代表列 for(s=i,t=0; t<Q; t++) if(dp[s][t]==1 && t!=j) return false;//判斷行 for(t=j,s=0; s<Q; s++) if(dp[s][t]==1 && s!=i) return false;//判斷列 for(s=i-1,t=j-1; s>=0&&t>=0; s--,t--) if(dp[s][t]==1) return false;//判斷左上方 for(s=i+1,t=j+1; s<Q&&t<Q;s++,t++) if(dp[s][t]==1) return false;//判斷右下方 for(s=i-1,t=j+1; s>=0&&t<Q; s--,t++) if(dp[s][t]==1) return false;//判斷右上方 for(s=i+1,t=j-1; s<Q&&t>=0; s++,t--) if(dp[s][t]==1) return false;//判斷左下方 return true; } }

4.總結:其實感覺回溯法有類似窮舉,把所有的結果都列出來。只是回溯法,把結果變成了一棵樹,如果在某個結點的時候,已經不滿足條件了,那後面的選擇肯定不滿足條件,這樣就節省了遍歷所有的結果的時間。提高了效率。