Java实现八皇后

实验题目   回溯法实现8皇后问题

实验要求   a.掌握递归回溯算法的基本思想。  

             b.学习掌握应用面向对象通用回溯程序框架解决实际问题。  提高面向对象编程的技能。

作业描述:在8*8格的棋盘上放置彼此不受攻击的8个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。8后问题等价于在n*n格的棋盘上放置8个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

 

package pku.java;

import java.util.ArrayList;
import java.util.List;

public class Main {
    private static int SIZE = 8;
    private static int TotalNumber = 0;
    private static List<boolean[][]> ChessBoards = new ArrayList<boolean[][]>();

    public static void main(String[] args) {
        boolean[][] chessboard = new boolean[SIZE][SIZE];
        for (int i = 0; i < SIZE; ++i) {
            for (int j = 0; j < SIZE; ++j) {
                chessboard[i][j] = false;
            }
        }
        Main Test = new Main();
        Test.put(chessboard, 0);
        Test.print(ChessBoards.get((int) (Math.random() * 1000)
                % ChessBoards.size()));
        System.out.println(TotalNumber);
    }

    public void print(boolean[][] chessboard) {
        for (int i = 0; i < SIZE; i++) {
            for (int k = 0; k < SIZE; k++) {
                if (chessboard[i][k] == true)
                    System.out.print("# ");
                if (chessboard[i][k] == false)
                    System.out.print(". ");
            }
            System.out.println();
        }
    }

    public void put(boolean[][] chessboard, int level) {
        // 放皇后
        if (level == SIZE - 1) {
            for (int j = 0; j < SIZE; j++) {
                chessboard[level][j] = true;
                if (safeJudge(chessboard, level, j)) {
                    // 放最后一个皇后
                    boolean[][] temp = new boolean[SIZE][SIZE];
                    for (int i = 0; i < SIZE; i++) {
                        for (int k = 0; k < SIZE; k++) {
                            temp[i][k] = chessboard[i][k];
                        }
                    }
                    ChessBoards.add(temp);
                    TotalNumber++;
                }
                chessboard[level][j] = false;
            }
        } else {
            for (int j = 0; j < SIZE; j++) {
                chessboard[level][j] = true;
                if (safeJudge(chessboard, level, j)) {
                    put(chessboard, level + 1);
                }
                chessboard[level][j] = false;
            }
        }
    }

    public boolean safeJudge(boolean[][] chessboard, int x, int y) {
        // 放皇后时,判断放下是否安全,因为是逐行放,水平方向不会冲突
        // int x_count = 0;
        int y_count = 0;
        // x-direction
        // for (int j = 0; j < SIZE; j++) {
        // if (chessboard[x][j] == true) {
        // ++x_count;
        // }
        // if (x_count > 1)
        // return false;
        // }
        // y-direction
        for (int i = 0; i < SIZE; i++) {
            if (chessboard[i][y] == true) {
                ++y_count;
            }
            if (y_count > 1)
                return false;
        }
        // oblique-direction
        // 主对角线
        int z_count = 0;
        for (int i = x, j = y; i >= 0 && j >= 0; --i, --j) {
            if (chessboard[i][j] == true)
                ++z_count;
            if (z_count > 1)
                return false;
        }
        z_count = 0;
        for (int i = x, j = y; i < SIZE && j < SIZE; ++i, ++j) {
            if (chessboard[i][j] == true)
                ++z_count;
            if (z_count > 1)
                return false;
        }
        // 副对角线
        int w_count = 0;
        for (int i = x, j = y; i >= 0 && j < SIZE; --i, ++j) {
            if (chessboard[i][j] == true)
                ++w_count;
            if (w_count > 1)
                return false;
        }
        w_count = 0;
        for (int i = x, j = y; i < SIZE && j >= 0; ++i, --j) {
            if (chessboard[i][j] == true)
                ++w_count;
            if (w_count > 1)
                return false;
        }
        return true;
    }
}

 

posted @ 2013-09-20 23:30  丶Blank  阅读(958)  评论(0编辑  收藏  举报