八皇后问题(回溯法)

这篇具有很好参考价值的文章主要介绍了八皇后问题(回溯法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

什么是八皇后

八皇后问题怎么解决?

什么是回溯法

回溯法的模板

八皇后问题的核心代码

判断皇后位置是否可行

总体实现代码

每日一句:

种一棵树的最好时间是十年前,其次是现在。


八皇后问题(回溯法)

什么是八皇后

八皇后问题(英文:Eight queens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。

问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。八皇后问题(回溯法)

八皇后问题怎么解决?

八皇后的解决办法有很多种,我们这里采取回溯法解决。

什么是回溯法

回溯法的处理思想类似于枚举搜索,我们枚举出每一种情况,然后在根据条件进行筛选,找到满足期望的值。我们把求解过程分为多个阶段,每个阶段我们都会面临一个十字路口,我们随便找一条路,走不通后,就回到上一个十字路口,选择另一个十字路口进行下一步,知道遍历完整个枚举情况。

回溯法的模板

在面临较简单的回溯问题是可以使用以下模板

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

八皇后问题的核心代码

int []Queen=new int[8];//存取皇后所在列的位置
    public void eightQueen(int row){

        if (row==8){//当row等于8时说明八个皇后都放置好了
            printQueens(Queen);//打印八皇后
            return;
        }
        for (int column = 0; column < 8; column++) {
           if (isOk(row,column)){//这里判断是否可以放在这个位置
               Queen[row]=column;//放置皇后
               eightQueen(row+1);
           }
        }
    }

 那么有小伙伴就迷惑了,八皇后不应该是八行八列吗,为什么数组只是一个一维数组。这里就用到了回溯法的思想,把八行八列分成了八行,每一行都独立,而一维数组则只用来存取皇后的列坐标,行坐标由数组的下标代替。

判断皇后位置是否可行

public boolean isOk(int row,int column){
        int leftup=column-1,rightup=column+1;
        for (int i = row-1; i >=0 ; --i) {
            if (Queen[i]==column) return false;//看垂直方向是否有皇后
            if (leftup>=0){
                if (Queen[i]==leftup) return false;//看左上角斜线是否有皇后
            }
            if (rightup<8){
                if (Queen[i]==rightup) return false;//看右上角斜线是否有皇后
            }
            --leftup;
            ++rightup;
        }
        return true;
    }

判断位置可行的条件是,是否存在有皇后处在同一列,同一行(同一行的情况不存在,因为row一直加1),同一斜线。 

那么判断同一列我们只要看一维数组中是否有值与将要放置的皇后的列一致,如果一致我们为判断false;

那么如何判断是否在同一条斜线,

假设一个点A AA的坐标是[ a , b ] [a,b][a,b],那么和该点在同一斜线上的点A 有四种,分别是
[ a + x , b + x ] 、 [ a − x , b − x ] 、 [ a + x , b − x ] 、 [ a − x , b + x ] 

而我们只考虑左右上角的位置是否存在同一条斜线,那么为什么不考虑下角是否存在呢,因为我们的皇后还没排到左右下角,所以只考虑 [ a − x , b + x ] 和[ a − x , b − x ]这两种情况。

我们通过让x等于1时来达到,当处于同一斜线时,斜线分为四十五度,则行和列相等时,在同一斜线上,判断为false.文章来源地址https://www.toymoban.com/news/detail-405751.html

八皇后总体实现代码

public static void main(String[] args) {
        Solution1 solution=new Solution1();
        solution.eightQueen(0);
    }
    int []Queen=new int[8];
    int count=0;
    public void eightQueen(int row){

        if (row==8){
            count++;
            printQueens(Queen);
            return;
        }
        for (int column = 0; column < 8; column++) {
           if (isOk(row,column)){

               Queen[row]=column;
               eightQueen(row+1);
           }
        }
    }
    public boolean isOk(int row,int column){
        int leftup=column-1,rightup=column+1;
        for (int i = row-1; i >=0 ; --i) {
            if (Queen[i]==column) return false;//看垂直方向是否有皇后
            if (leftup>=0){
                if (Queen[i]==leftup) return false;//看左上角斜线是否有皇后
            }
            if (rightup<8){
                if (Queen[i]==rightup) return false;//看右上角斜线是否有皇后
            }
            --leftup;
            ++rightup;
        }
        return true;
    }
    private void printQueens(int []Queen){
        for (int row = 0; row < 8; row++) {
            for (int column = 0; column < 8; column++) {
                if (Queen[row]==column) System.out.print("   Q   ");
                else System.out.print("   *   ");
            }
            System.out.println();
        }
        System.out.print(count);
        System.out.println();
    }
}

每日一句:

种一棵树的最好时间是十年前,其次是现在。  

到了这里,关于八皇后问题(回溯法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法:回溯算法(以解决n皇后问题为例)

    基本思想:回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。八皇后问题就是回溯算法的典型,第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后

    2024年02月05日
    浏览(22)
  • python中级篇1:n皇后问题(回溯算法)

    hello!大家好,我是浪矢秀一。最近经历了许多事情,终于是恢复1次更新了。那么今天呢,我们来学习中级篇,需要学过不少python知识的人来学习。好了,废话不多说,我们进入今天的课程!   在1个n*n的国际象棋棋盘上,放置n个皇后,要求:同1行、同1列、同1斜线上只能有1个皇后。   既然

    2024年02月03日
    浏览(23)
  • 算法与数据结构——递归算法+回溯算法——八皇后问题

    八皇后问题是一个经典的回溯算法问题,目的是在8×8的国际象棋棋盘上放置八个皇后,使得没有皇后可以互相攻击(即没有两个皇后在同一行、同一列或同一对角线上)。 回溯算法是一种解决问题的算法,它通过尝试所有可能的解决方案来解决问题。在八皇后问题中,计算

    2024年02月09日
    浏览(42)
  • 八皇后问题,秒懂递归回溯(有图详解|c语言)

    目录 👸🏻前言 👸🏻题目介绍 👸🏻引入: 👸🏻解决思路: 👸🏻理论存在,实践开始! 👸🏻难点1:如何表示对角线被占领? 👸🏻难点2:如何用递归的方法来放皇后? 👸🏻难点3:如何实现回溯? 👸🏻难点4:如何实现皇后位置的输出? 👸🏻全部代码如下: 👸

    2024年02月02日
    浏览(21)
  • N皇后问题详解:回溯算法的应用与实践(dfs)

    题目如上图所示,在一个 n*n 的国际象棋棋盘上怎么摆放能使得皇后互相攻击不到(也就是在 任意一列、一行、一条对角线上都不存在两个皇后 ) 1.DFS 想要解决这个问题,我们可以使用dfs也就是 深度优先遍历 ,深度优先搜索的步骤为先递归到底再回溯上来,顾名思义,df

    2024年03月26日
    浏览(39)
  • 【力扣 51】N 皇后(回溯+剪枝+深度优先搜索)

    按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后

    2024年02月22日
    浏览(26)
  • 【算法】回溯:与递归,dfs的同质与分别,剪枝与恢复现场的详细理解,n皇后的回溯解法及算法复杂度分析。

    目录 ​编辑 1.什么是回溯 2.关于剪枝 3.关于恢复现场 4.题目:二叉树的所有路径(凸显恢复现场:切实感受回溯与深搜) 问题分析 ①函数设置为:void Dfs(root) ②函数设置为:void Dfs(root,path) 解题思想:使⽤深度优先遍历(DFS)求解。 代码实现 5.N后问题 问题分析 4皇后的放置

    2024年04月16日
    浏览(29)
  • Day31 46全排列 47全排列II 回溯去重tips 51N皇后 37解数独

    给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]  排列问题与组合问题的不同之处就在于,没有startIndex,同时需要设置一个used数组,遍历过的就设置成true,下次遇到时跳过。 给定一个可包含重

    2024年01月20日
    浏览(31)
  • C#八皇后算法:回溯法 vs 列优先法 vs 行优先法 vs 对角线优先法

    目录 1.八皇后算法(Eight Queens Puzzle) 2.常见的八皇后算法解决方案 (1)列优先法(Column-First Method): (2)行优先法(Row-First Method): (3)对角线优先法(Diagonal-First Method): (4)回溯法(Backtracking):        皇后问题是一个古老而著名的问题,它实质上就是使棋

    2024年03月22日
    浏览(28)
  • DFS(深度优先遍历、N皇后问题、2N皇后问题)

    目录 一、回溯法与深度优先搜索(DFS) 二、DFS与二叉树的前序遍历 2.1、二叉树的前序遍历 2.2、DFS 全排列  2.3、分析 三、N皇后问题 1. 回溯法: 是一种通过探索所有可能的候选解来找出所有解的算法。如果候选解被确认不是一个解的话(或者至少不是最后一个解),回溯法

    2024年03月21日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包