八皇后谜题是经典的一个问题,其解法一共有种!

其定义:

  1. 首先定义一个8*8的棋盘
  2. 我们有八个皇后在手里,目的是把八个都放在棋盘中
  3. 位于皇后的水平和垂直方向的棋格不能有其他皇后
  4. 位于皇后的斜对角线上的棋格不能有其他皇后
  5. 解出能将八个皇后都放在棋盘中的摆法

这个问题通常使用两种方法来求解:

  1. 穷举法
  2. 回溯法(递归)

本文章通过回溯法来求解,回溯法对比穷举法高效许多,让我们学习如何实现吧!

实现思想:

  1. 我们先在棋盘的第0行第1个棋格放下第一个皇后
  2. 下一行寻找一个不冲突的棋格放下下一个皇后
  3. 循环第2步
  4. 如果到某一行全部8个格子都无法放下皇后,回溯到前一行,继续寻找下一个不冲突的棋格
  5. 把8个皇后都放在棋盘之后,输出或存储摆法,结束

实现(Java)算法:

定义棋盘

我们通过一个二维整型数组表示一个棋盘

数组内为1是放下了的皇后,0则是空白的棋格

我们下下面定义一个方法:通过检查棋格是否为1来知道是不是有皇后

  1. // 定义一个棋盘
  2. static int chessboard[][] = new int[8][8];

检查冲突

这个方法用来检查冲突:在水平垂直方向、斜角上的棋格有无其他皇后,传入的(x,y)是需要检查的棋格,如检查棋格(1,0)即棋盘的第2行第1个,是否能放下皇后。

  1. // 检查是否符合规则
  2. private static boolean checked(int x,int y){
  3. for(int i = 0;i<y;i++){
  4. // 检查水平垂直方向
  5. if(chessboard[x][i]==1)return false;
  6. // 检测左斜角
  7. if((x-y+i>=0)&&chessboard[x-y+i][i]==1)return false;
  8. // 检查右斜角
  9. if((x+y-i<=7)&&chessboard[x+y-i][i]==1)return false;
  10. }
  11. return true;
  12. }

放下皇后

我们在每一行都执行以下步骤,通过从第1个棋格到第8个遍历寻找可以放下皇后的棋格

如果放下了皇后,我们就可以继续放下下一个了,将行数+1,我们递归调用这个方法

  1. public static boolean solve(int y){
  2. // 将一行的8种情况都扫描一次
  3. for(int i = 0;i<8;i++){
  4. // 每次检测前都将当前行清空,避免脏数据
  5. for(int k = 0;k<8;k++)chessboard[k][y]=0;
  6. if(checked(i, y)){
  7. chessboard[i][y] = 1;
  8. // 当前一行已经获得解法,进入下一行
  9. solve(y+1);
  10. }
  11. }
  12. return false;
  13. }

算法边界

当我们放下了所有8个皇后后,需要一个终止条件,我们在行数y=8时,结束算法

同时你可以输出一个棋盘摆法了!恭喜你已经把这个经典问题解决了!

  1. // 当y=8时,已经找到一种解决方法
  2. if(y == 8){
  3. return true;
  4. }

以下是完整的算法

  1. public class EightQueen{
  2. // 定义一个棋盘
  3. static int chessboard[][] = new int[8][8];
  4. // 计数器
  5. static int count = 0;
  6.  
  7. // 解题方法
  8. public static boolean solve(int y){
  9. // 当y=8时,已经找到一种解决方法,计数器加一并输入摆法
  10. if(y == 8){
  11. System.out.println("solved!");
  12. show();
  13. count++;
  14. return true;
  15. }
  16. // 将一行的8种情况都扫描一次
  17. for(int i = 0;i<8;i++){
  18. // 每次检测前都将当前行清空,避免脏数据
  19. for(int k = 0;k<8;k++)chessboard[k][y]=0;
  20. if(checked(i, y)){
  21. chessboard[i][y] = 1;
  22. // 当前一行已经获得解法,进入下一行
  23. solve(y+1);
  24. }
  25. }
  26. return false;
  27. }
  28. // 检查是否符合规则
  29. private static boolean checked(int x,int y){
  30. for(int i = 0;i<y;i++){
  31. // 检查垂直方向
  32. if(chessboard[x][i]==1)return false;
  33. // 检测左斜角
  34. if((x-y+i>=0)&&chessboard[x-y+i][i]==1)return false;
  35. // 检查右斜角
  36. if((x+y-i<=7)&&chessboard[x+y-i][i]==1)return false;
  37. }
  38. return true;
  39. }
  40. // 输出棋盘摆法
  41. public static void show(){
  42. for(int i = 0;i<8;i++){
  43. for(int j = 0;j<8;j++){
  44. System.out.print(chessboard[j][i]+" ");
  45. }
  46. System.out.println("");
  47. }
  48. }
  49. }

在执行这个算法后:

  1. have 92 ways to sovle it!

我们获得了92种棋盘摆法!

算法——八皇后问题(eight queen puzzle)之回溯法求解的更多相关文章

  1. 7, java数据结构和算法: 八皇后问题分析和实现 , 递归回溯

    什么是八皇后问题: 指的是,在一个8 * 8的棋盘中, 放置8个棋子, 保证这8个棋子相互之间, 不在同一行,同一列,同一斜线, 共有多少种摆法? 游戏连接: http://www.4399.com/ ...

  2. 54. 八皇后问题[eight queens puzzle]

    [本文链接] http://www.cnblogs.com/hellogiser/p/eight-queens-puzzle.html [题目] 在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即 ...

  3. USACO 1.5.4 Checker Challenge跳棋的挑战(回溯法求解N皇后问题+八皇后问题说明)

    Description 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行,每列,每条对角线(包括两条主对角线的所有对角线)上都至多有一个棋子. 列号 0 1 2 3 4 5 6 ...

  4. 回溯法求解n皇后和迷宫问题

    回溯法是一种搜索算法,从某一起点出发按一定规则探索,当试探不符合条件时则返回上一步重新探索,直到搜索出所求的路径. 回溯法所求的解可以看做解向量(n皇后坐标组成的向量,迷宫路径点组成的向量等),所有解 ...

  5. 回溯法——求解N皇后问题

    问题描写叙述 八皇后问题是十九世纪著名数学家高斯于1850年提出的.问题是:在8*8的棋盘上摆放8个皇后.使其不能互相攻击,即随意的两个皇后不能处在允许行.同一列,或允许斜线上. 能够把八皇后问题拓展 ...

  6. 算法设计与分析——n后问题(回溯法+位运算)

    一.问题描述 在n×n格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 二.算法设计 解n后问题的回溯算法描述如下: #include ...

  7. 『嗨威说』算法设计与分析 - 回溯法思想小结(USACO-cha1-sec1.5 Checker Challenge 八皇后升级版)

    本文索引目录: 一.回溯算法的基本思想以及个人理解 二.“子集和”问题的解空间结构和约束函数 三.一道经典回溯法题点拨升华回溯法思想 四.结对编程情况 一.回溯算法的基本思想以及个人理解: 1.1 基 ...

  8. 【算法导论】八皇后问题的算法实现(C、MATLAB、Python版)

    八皇后问题是一道经典的回溯问题.问题描述如下:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉?         看到这个问题,最容易想 ...

  9. 九度OJ 1140:八皇后 (八皇后问题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:795 解决:494 题目描述: 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * ...

随机推荐

  1. 正则化(Regularization)本质

    参考: http://www.cnblogs.com/maybe2030/p/9231231.html https://blog.csdn.net/wsj998689aa/article/detail ...

  2. HTML&CSS_基础01

    一.预备知识: # 1. HTML5 是 W3C 与 WHATWG 合作的结果.    W3C 指 World Wide Web Consortium,万维网联盟.    WHATWG 指 Web H ...

  3. v-for 循环element-ui菜单

    vue 使用了element-ui的菜单组件, 这个组件的el-menu-item项上,有一个属性index,值是字符串类型, 在使用v-for的index时,它是一个数值型,所以如果直接写index ...

  4. Re.常系数齐次递推

    前言 嗯   我之前的不知道多少天看这个的时候到底在干什么呢 为什么那么..  可能大佬们太强的缘故 最后仔细想想思路那么的emmm 不说了  要落泪了 唔唔唔 前置 多项式求逆 多项式除法/取模 常 ...

  5. Linux-Jenkins安装部署

    Jenkins 安装及插件安装 Jenkins简介: Jenkins只是一个平台,真正运作的都是插件.这就是jenkins流行的原因,因为jenkins什么插件都有 Hudson是Jenkins的前身 ...

  6. FTP文件上传 支持断点续传 并 打印下载进度(二) —— 单线程实现

    这个就看代码,哈哈哈哈哈  需要用到的jar包是: <dependency> <groupId>commons-net</groupId> <artifact ...

  7. 洛谷P1066 2^k进制数(题解)(递推版)

    https://www.luogu.org/problemnew/show/P1066(题目传送) (题解)https://www.luogu.org/problemnew/solution/P106 ...

  8. (二叉树 递归) leetcode 145. Binary Tree Postorder Traversal

    Given a binary tree, return the postorder traversal of its nodes' values. Example: Input: [1,null,2, ...

  9. easyUI文本框获得焦点,失去焦点

    easyUI帮助文档对于文本框的操作没有提供直接获得焦点,或者失去焦点的方法,我们可以采用以下写法来实现. 获得焦点: $('input',$('#文本框Id').next('span')).focu ...

  10. Apache Hadoop 2.9.2 的集群管理之服役和退役

    Apache Hadoop 2.9.2 的集群管理之服役和退役 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 随着公司业务的发展,客户量越来越多,产生的日志自然也就越来越大来,可能 ...