java回溯法解決n皇后問題
先看問題吧
問題描述:八皇后問題是一個以國際象棋為背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。
關於n皇后問題相關的解法很多,在這裡大家可以看看我的寫法,註釋也比較詳細了,需要注意的是就是大家怎麼去思考這個問題,怎麼理解行,列,對角線的衝突。
好了貼程式碼:
class Solve {
int q;// 皇后個數
int[] a;// 存放皇后的陣列
int sum = 0;// 解的個數
// 設定皇后個數
public int total(int q) {
this.q = q;
a = new int[q + 1];
back(1);
return sum;
}
/*
* 判斷當前位置是否放置皇后 對角線衝突條件 Math.abs(h-i)==Math.abs(a[h]-a[i]) 列衝突條件 a[h]==a[i]
* h是當前所在的行 當前行的所有元素與前幾行的元素做對比,不滿足一旦衝突就返回,就是回溯的條件
*/
private boolean place(int h) {
for (int i = 1; i < h; i++) {
if (Math.abs(h - i) == Math.abs(a[h] - a[i]) || a[h] == a[i]) {
return false;
}
}
return true;
}
// 回溯
private void back(int s) {
if (s > q) {
// 第一層的當前位置的情況 找到了一個解 需執行第一層第二個位置
sum++;
} else {
// q皇后數
for (int i = 1; i <=q; i++) {
a[s] = i;// 每一層皇后的位置
// 判斷當前層的位置是否能存放皇后
if (place(s)) {
// 如果符合需求進入下一層 但是要注意當前的for迴圈是否結束完成這裡是回溯的難點
back(s + 1);
}
}
}
}
}
public class Nqueen {
public static void main(String[] args) {
// TODO Auto-generated method stub
Solve s = new Solve();
System.out.println(s.total(8));
}
}