數據結構與算法 --- 回溯算法

題目:八皇后問題
有一個 8x8 的棋盤,希望往裏放 8 個棋子(皇后),每個棋子所在的行、列、對角線,都不能有另一個棋子。找到所有滿足這種要求的放棋子方式
回溯的處理思想,有點類似枚舉搜索。我們枚舉所有的解,找到滿足期望的解。爲了有規律 地枚舉所有可能的解,避免遺漏和重複,我們把問題求解的過程分爲多個階段。每個階段, 我們都會面對一個岔路口,我們先隨意選一條路走,當發現這條路走不通的時候(不符合期 望的解),就回退到上一個岔路口,另選一種走法繼續走。
 
Java代碼如下:
 
public class Test1 {
    /**
     *八皇后問題:
     * 有一個 8x8 的棋盤,希望往裏放 8 個棋子(皇后),每個棋子所在的行、列、對角線
     * 都不能有另一個棋子。找到所有滿足這種要求的放棋子方式
     */
    @Test
    public void test1(){
       cal8Queens(0);
    }


    int[]   result = new int[8]; //存儲每個列的標號
    //遞歸實現算法
    public void cal8Queens(int row){
        if(row == 8){
            printArray(result);
            return;
        }
        for(int column=0;column<8;column++){
            if(isOk(row,column)){
                result[row] = column;
                cal8Queens(row+1);
            }
        }


    }
    //滿足 8 皇后的規則要求
    public boolean isOk(int row,int column){
        int leftCl  = column-1;
        int rightCl = column+1;
        for(int i=row-1;i>=0;i--){

            if(result[i] == column)
                return false;
            if(leftCl>=0&&result[i] == leftCl){  //判斷左上對角線是否滿足無棋子的要求
                return false;
            }
            if(rightCl<8&&result[i] == rightCl){ //判斷右上對角線是否滿足無棋子的要求
                return false;
            }
            leftCl--;
            rightCl++;

        }

        return true;
    }

    public void printArray(int[] array){
        int row = 0;
        for(int a:array){
            System.out.println((row++)+","+a);
        }
        System.out.println("-------------------------------------");
    }
}

 

輸出爲每種可能 (只列出第一種排列方式,第一列爲行號,第二列爲列號)
 
0,0
1,4
2,7
3,5
4,2
5,6
6,1
7,3

 

 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章