可视化讲解:什么是八皇后问题?

前言

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

概念介绍

1. 八皇后问题起源

  • 八皇后问题(英文:Eight queens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。
  • 问题描述:在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。
  • 请问一共有多少种摆法?

原理讲解

  • 由于篇幅限制,我们将八皇后问题简化为4皇后问题来讲解其原理(八皇后问题和4皇后问题的原理是一致的)
  1. 第一步,我们从第一行开始,遍历第一行中所有的列,找到第一个适合放置皇后的位置。皇后位置用黑色背景表示。此时效果如下图所示
    在这里插入图片描述
  2. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第1个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第2个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  3. 第二步,我们从第二行开始,遍历第二行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。皇后位置用黑色背景表示。此时效果如下图所示
    在这里插入图片描述
  4. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第2个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第3个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  5. 第三步,我们从第三行开始,遍历第三行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。由于在第三行找不到放置皇后的位置,所以我们进行回退,重新放置第2个皇后的位置。此时效果如下图所示
    在这里插入图片描述
  6. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第2个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第3个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  7. 第四步,我们从第三行开始,遍历第三行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。皇后位置用黑色背景表示。此时效果如下图所示
    在这里插入图片描述
  8. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第3个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第4个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  9. 第五步,我们从第四行开始,遍历第四行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。由于在第四行找不到放置皇后的位置,所以我们进行回退。由于第2个,第3个皇后已经没有可选的位置,所以我们重新放置第1个皇后的位置。此时效果如下图所示
    在这里插入图片描述
  10. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第1个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第2个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  11. 第六步,我们从第二行开始,遍历第二行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。皇后位置用黑色背景表示。此时效果如下图所示
    在这里插入图片描述
  12. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第2个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第3个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  13. 第七步,我们从第三行开始,遍历第三行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。皇后位置用黑色背景表示。此时效果如下图所示
    在这里插入图片描述
  14. 由于任意两个皇后不得处在同一行、同一列或者同一对角斜线上。所以第3个皇后所在的行、列和对角线上的位置都是危险位置,不能再放置第4个皇后。危险位置我们用红色背景表示,安全位置我们用绿色背景表示。此时效果如下图所示
    在这里插入图片描述
  15. 第八步,我们从第四行开始,遍历第四行中所有的列,在安全位置范围内找到第一个适合放置皇后的位置。皇后位置用黑色背景表示。此时效果如下图所示
    在这里插入图片描述
  16. 至此,我们已经成功的在4×4的象棋上摆放四个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。当然这只是其中一种解法,还有另一种解法。留着读者自行研究。

效果展示

在这里插入图片描述

更多算法学习请关注我的公众号

在这里插入图片描述

说明

  • 在公众号中回复“算法源码”即可获取十大经典算法源码
  • 在公众号中回复“算法书籍”即可获取经典入门算法书籍
  • 在公众号中回复“数据结构”即可获取数据结构相关源码
解决八皇后问题。从第一行开始,放第一个皇后,放好皇后以后,她所在的行,列和对角线上的每一个位置就是她的管辖范围,别的皇后没有权利干涉,否则死无藏身之地。 然后,第二个皇后,从第二行的第一列开始判断所在的位置是否是别的皇后的管辖范围,找到第一个还没有被占据的位置,则将其占为己有。暂时,该皇后停在该位置。然后,第三个到第八个皇后依次从第三行,第四行,… ,到第八行的第一列开始寻求自己的位置。假如到第i个皇后时,已经没有任何位置可选,则第i-1个皇后必须往后移动进行协调,同样,假如第i-1个皇后往后移动时没有找到空位置,则第i-2个皇后必须往后移动,进行协调,当找到空位置时,暂时停下,将下一个皇后重新从第一列开始寻找空位置。重复上述过程,直到所有皇后都停下来。则得到了第一个解。要想产生所有的解,则当产生第一个解以后,第八个皇后往后移动,找下一个可以利用的空位置,找不到,则第七个皇后必须往后移动,若找到空位置则停下,第八个皇后从第八行第一列重新试探,找到空位置。一直这样,直到第一个皇后将第一行遍历完。得到的解就是所有解。 三、 概要设计: ***************类型及相关变量定义***************** //位置信息类型 typedef struct { int row; int col; }PosType; //皇后类型 typedef struct Queen{ PosType pos; int number; //第几号皇后 }QueenType; //栈节点类型 typedef struct Note{ QueenType queen; struct Note *next; }NoteType; //棋盘,某一位置chessboard[i][j]上有皇后,则该位的值变为皇后序号。同样,该皇后的势 //力范围内的位置上的值全部变为该皇后的序号。 int chessboard[8][8]; //结果集,共92种解,每一种解中记录8个位置信息。 PosType ResultSet[92][8]; //定义一个栈,保存信息 Typedef struct{ NoteType head; Int size; }QueenStack; //定义一个栈,存放皇后信息 QueenStack qstack; *************相关操作**************** //初始化棋盘,开始时每个位置上都没有皇后,值全为0;并给8个皇后编号。 void initChessboard(); //回溯求八皇后问题的所有解,皇后协调算法 void queenCoordinate(); //输出所有解 void printResult();
二、 算法思想: 采用回溯法解决八皇后问题。从第一行开始,放第一个皇后,放好皇后以后,她所在的行,列和对角线上的每一个位置就是她的管辖范围,别的皇后没有权利干涉,否则死无藏身之地。 然后,第二个皇后,从第二行的第一列开始判断所在的位置是否是别的皇后的管辖范围,找到第一个还没有被占据的位置,则将其占为己有。暂时,该皇后停在该位置。然后,第三个到第八个皇后依次从第三行,第四行,… ,到第八行的第一列开始寻求自己的位置。假如到第i个皇后时,已经没有任何位置可选,则第i-1个皇后必须往后移动进行协调,同样,假如第i-1个皇后往后移动时没有找到空位置,则第i-2个皇后必须往后移动,进行协调,当找到空位置时,暂时停下,将下一个皇后重新从第一列开始寻找空位置。重复上述过程,直到所有皇后都停下来。则得到了第一个解。要想产生所有的解,则当产生第一个解以后,第八个皇后往后移动,找下一个可以利用的空位置,找不到,则第七个皇后必须往后移动,若找到空位置则停下,第八个皇后从第八行第一列重新试探,找到空位置。一直这样,直到第一个皇后将第一行遍历完。得到的解就是所有解。 三、 概要设计: ***************类型及相关变量定义***************** //位置信息类型 typedef struct { int row; int col; }PosType; //皇后类型 typedef struct Queen{ PosType pos; int number; //第几号皇后 }QueenType; //栈节点类型 typedef struct Note{ QueenType queen; struct Note *next; }NoteType; //棋盘,某一位置chessboard[i][j]上有皇后,则该位的值变为皇后序号。同样,该皇后的势 //力范围内的位置上的值全部变为该皇后的序号。 int chessboard[8][8]; //结果集,共92种解,每一种解中记录8个位置信息。 PosType ResultSet[92][8]; //定义一个栈,保存信息 Typedef struct{ NoteType head; Int size; }QueenStack; //定义一个栈,存放皇后信息 QueenStack qstack; *************相关操作**************** //初始化棋盘,开始时每个位置上都没有皇后,值全为0;并给8个皇后编号。 void initChessboard(); //回溯求八皇后问题的所有解,皇后协调算法 void queenCoordinate(); //输出所有解 void printResult();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值