美文网首页
八皇后问题一种解法

八皇后问题一种解法

作者: hswwjp | 来源:发表于2019-03-12 17:15 被阅读0次

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

定义二维数组棋盘

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

    /**
     * 检查落点是否符合规则
     *
     * @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;
    }
清零每行

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


不清零的后果

相关文章

  • 八皇后问题一种解法

    首先定义一个二维数组表示棋盘: 检查方式:每次落点检查 纵向/ 左斜方/ 右斜方是否满足条件 落点的方式:从上往下...

  • 八皇后问题解法

    八皇后问题解法 什么事八皇后问题 国际象棋中的皇后,可以横向、纵向、斜向移动。如何在一个8X8的棋盘上放置8个皇后...

  • 八皇后和约瑟夫问题

    今天在写C语言报告的时候,收获了两种算法的实现,分别是八皇后和约瑟夫问题。 八皇后:总的来说,八皇后问题就是一种b...

  • 八皇后的递归解法

    最近在看PiL3,今天在做习题的时候遇见了八皇后问题,当时示例代码并没有仔细看,等到写的时候发现老是有问题。后来去...

  • n皇后问题的解法

    解法一 解法二回溯算法

  • [JavaScript刷LeetCode]-n皇后问题

    n皇后问题,js解法如下: js解LeetCode github地址: https://github.com/Li...

  • 11.数据结构—八皇后问题(回溯法)

    11.1 八皇后问题 八皇后问题是以国际象棋为背景的问题:有八个皇后(可以当成八个棋子),如何在 88 的棋盘中放...

  • 算法(03)回溯

    八皇后问题

  • 八皇后问题(N皇后问题)

    八皇后问题是一个经典的递归回溯问题。 描述 八皇后问题是在一个 8*8 的棋盘上放置皇后,要求其放置后满足同一行,...

  • 八皇后问题

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在...

网友评论

      本文标题:八皇后问题一种解法

      本文链接:https://www.haomeiwen.com/subject/wkpnpqtx.html