八皇后问题一种解法

首先定义一个二维数组表示棋盘:

定义二维数组棋盘

检查方式:
每次落点检查 纵向/ 左斜方/ 右斜方是否满足条件

    /**
     * 检查落点是否符合规则
     *
     * @param x 横轴(行)
     * @param y 纵轴(列)
     * @return {@code true} 可落点, {@code false} 不能落点
     */
    private boolean check(int x, int y) {
        for (int i = 0; i < y; i++) {
            // 检查纵向
            if (chessBoard[x][i] == 1) {
                return false;
            }
            // 检查左斜方
            if (x - 1 - i >= 0 && chessBoard[x - 1 - i][y - 1 - i] == 1) {
                return false;
            }
            // 检查右斜方
            if (x + 1 + i < MAX_NUM && chessBoard[x + 1 + i][y - 1 - i] == 1) {
                return false;
            }
        }
        return true;
    }
检查方式

落点的方式:
从上往下, 要求从上往下每一行的落点都能满足条件

    /**
     * 落点皇后
     *
     * @param y 纵轴(列)
     * @return {@code true or false} y行以下落点完成
     */
    private boolean settleQueen(int y) {
        // 行数超过8, 已经找到答案
        if (y == MAX_NUM) {
            return true;
        }
        // 遍历当前行, 逐一格子验证
        for (int i = 0; i < MAX_NUM; i++) {
            // 为当前行清零,以免在回溯的时候出现脏数据
            for (int x = 0; x < MAX_NUM; x++) {
                chessBoard[x][y] = 0;
            }
            // 检查是否符合规则, 如果符合, 更改元素值并进一步递归
            if (check(i, y)) {
                chessBoard[i][y] = 1;
                // 递归如果返回 true, 说明下层已找到解法, 无需继续循环
                if (settleQueen(y + 1)) {
                    return true;
                }
            }
        }
        return false;
    }

打印排序方式:

    /**
     * 打印棋盘当前值
     *
     */
    private void printChessBoard() {
        for (int j = 0; j < MAX_NUM; j++) {
            for (int i = 0; i < MAX_NUM; i++) {
                System.out.print((chessBoard[i][j] == 0 ? "." : chessBoard[i][j]) + "\t");
            }
            System.out.println();
        }
    }

主方法:

    public static void main(String[] args) {
        EightQueen queen = new EightQueen();
        queen.settleQueen(0);
        queen.printChessBoard();
    }

注意:
若把清零每行的操作取消掉, 会遗留脏数据

    /**
     * 落点皇后
     *
     * @param y 纵轴(列)
     * @return {@code true or false} y行以下落点完成
     */
    private boolean settleQueen(int y) {
        // 行数超过8, 已经找到答案
        if (y == MAX_NUM) {
            return true;
        }
        // 遍历当前行, 逐一格子验证
        for (int i = 0; i < MAX_NUM; i++) {
            // 为当前行清零,以免在回溯的时候出现脏数据
//            for (int x = 0; x < MAX_NUM; x++) {
//                chessBoard[x][y] = 0;
//            }
            // 检查是否符合规则, 如果符合, 更改元素值并进一步递归
            if (check(i, y)) {
                chessBoard[i][y] = 1;
                // 递归如果返回 true, 说明下层已找到解法, 无需继续循环
                if (settleQueen(y + 1)) {
                    return true;
                }
            }
        }
        return false;
    }
清零每行

不清零的后果, 每一行往上层回溯


不清零的后果

你可能感兴趣的:(八皇后问题一种解法)