1. 程式人生 > >java回溯法解決n皇后問題

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));

    }

}