1.介绍

八皇后问题,是一个古老而著名的问题,是回溯算法的经典案例,该问题是国际西洋棋棋手马克斯.贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即

任意两个皇后都不能处于同一行、同一列、同一斜线。问有多少种摆法(92)。

2.思路分析

第一个皇后先放第一行第一列

第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二列,第三列,依次把所有列都放完,找到一个合适

继续放第三个皇后,还是第一列,第二列。。。知道第8个皇后也能放在一个不冲突的位置,算是找到一个正确解

当得到一个正确解时,在栈中退到上一个栈时,就会开始回溯,即:将第一个皇后,放到第一列的所有正确解,全部得到

然后回头继续放第一个皇后放第二列,后面继续循环执行执行1,2,4步骤

说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题. arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} //对应arr 下标 表示第几行,即第几个皇后,arr[i] = val , val 表示第i+1个皇后,放在第i+1行的第val+1列

3.图解

4.代码实现

  1. public class EightQueens
  2. {
  3. //定义一个max表示共有多少个皇后
  4. static int _max = ;
  5.  
  6. //定义数组arr,保存皇后放置位置的结果,比如 arr={0,4,7,5,2,6,1,3}
  7. static int[] _arr = new int[_max];
  8.  
  9. //初始化解法次数
  10. static int _count = ;
  11.  
  12. //初始化冲突次数
  13. static int _judgeCount = ;
  14. public static void Test()
  15. {
  16. EightQueens.Check();
  17.  
  18. Console.WriteLine($"一共有{_count}种解法");
  19.  
  20. Console.WriteLine($"一共判断冲突的次数{_judgeCount}次");
  21. }
  22.  
  23. /// <summary>
  24. ///编写一个方法,放置第n个皇后
  25. ///Check是每一次递归时,进入到Check中都有for(int i=0;i<_max;i++),因此会有回溯
  26. /// </summary>
  27. /// <param name="n"></param>
  28. private static void Check(int n)
  29. {
  30. if (n == _max) //当n=8,说明8个皇后已经方法,因为初始值从0开始
  31. {
  32. Print();
  33.  
  34. return;
  35. }
  36.  
  37. //依次放入皇后,并判断是否有冲突
  38. for (int i = ; i < _max; i++)
  39. {
  40. //先把当前这个皇后n,放到该行的第1列
  41. _arr[n] = i;
  42.  
  43. //判断当放置第n个皇后到i列时,是否冲突
  44. if (Judge(n))
  45. {
  46. //如果不冲突,接着放n+1个皇后,即开始递归
  47. Check(n + );
  48. }
  49.  
  50. //如果冲突,就继续执行arr[n]=i,即将第n个皇后,放置在本行的后移的一个位置
  51. }
  52. }
  53.  
  54. /// <summary>
  55. /// 查看当我们放置第n个皇后,就去检查该皇后是否和前面已经判断的皇后冲突
  56. /// </summary>
  57. /// <param name="n">表示第n个皇后</param>
  58. /// <returns></returns>
  59. private static bool Judge(int n)
  60. {
  61. _judgeCount++;
  62.  
  63. for (int i = ; i < n; i++)
  64. {
  65. //1._arr[i] == _arr[n] 表示判断第n个皇后,是否和前面的n-1个皇后在同一列
  66. //2.Math.Abs(n - i) == Math.Abs(_arr[n] - _arr[i])表示判断第n个皇后是否和第i个皇后在同一个斜线
  67. //取个例子:当 n=1的时候 也就是放置第2列 Math.Abs(1-0)==Math.Abs(1-0)=1
  68. //3.判断是否在同一行,没有必要,n每次都在递增
  69. if (_arr[i] == _arr[n] || Math.Abs(n - i) == Math.Abs(_arr[n] - _arr[i]))
  70. {
  71. return false;
  72. }
  73. }
  74.  
  75. return true;
  76. }
  77.  
  78. /// <summary>
  79. /// 皇后的摆放位置输出
  80. /// </summary>
  81. private static void Print()
  82. {
  83. _count++;
  84.  
  85. for (int i = ; i < _arr.Length; i++)
  86. {
  87. System.Console.Write(_arr[i] + " ");
  88. }
  89.  
  90. System.Console.WriteLine();
  91. }
  92. }

5.结果图

  1.  
  2. 一共有92种解法
  3. 一共判断冲突的次数15720

C#数据结构与算法系列(十四):递归——八皇后问题(回溯算法)的更多相关文章

  1. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  2. struts2官方 中文教程 系列十四:主题Theme

    介绍 当您使用一个Struts 2标签时,例如 <s:select ..../>  在您的web页面中,Struts 2框架会生成HTML,它会显示外观并控制select控件的布局.样式和 ...

  3. 闯祸了,生成环境执行了DDL操作《死磕MySQL系列 十四》

    由于业务随着时间不停的改变,起初的表结构设计已经满足不了如今的需求,这时你是不是想那就加字段呗!加字段也是个艺术活,接下来由本文的主人咔咔给你吹. 试想一下这个场景 事务A在执行一个非常大的查询 事务 ...

  4. SSE图像算法优化系列十:简单的一个肤色检测算法的SSE优化。

    在很多场合需要高效率的肤色检测代码,本人常用的一个C++版本的代码如下所示: void IM_GetRoughSkinRegion(unsigned char *Src, unsigned char ...

  5. 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  6. 浅谈压缩感知(二十四):压缩感知重构算法之子空间追踪(SP)

    主要内容: SP的算法流程 SP的MATLAB实现 一维信号的实验与结果 测量数M与重构成功概率关系的实验与结果 SP与CoSaMP的性能比较 一.SP的算法流程 压缩采样匹配追踪(CoSaMP)与子 ...

  7. MP实战系列(十四)之分页使用

    MyBatis Plus的分页,有插件式的,也有其自带了,插件需要配置,说麻烦也不是特别麻烦,不过觉得现有的MyBatis Plus足以解决,就懒得配置插件了. MyBatis Plus的资料不算是太 ...

  8. 八皇后,回溯与递归(Python实现)

    八皇后问题是十九世纪著名的数学家高斯1850年提出 .以下为python语句的八皇后代码,摘自<Python基础教程>,代码相对于其他语言,来得短小且一次性可以打印出92种结果.同时可以扩 ...

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

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

随机推荐

  1. 00016-layui 动态加载菜单 laytpl

    <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ i ...

  2. 50个SQL语句(MySQL版) 问题四

    --------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...

  3. SpringAOP使用及源码分析(SpringBoot下)

    一.SpringAOP应用 先搭建一个SpringBoot项目 <?xml version="1.0" encoding="UTF-8"?> < ...

  4. jchdl - RTL实例 - AndAnd

    https://mp.weixin.qq.com/s/JhUB3M1WhjAyUrN1HPIPTA   AndAnd是三输入与门模块,输出为相与的结果.   参考链接 https://github.c ...

  5. Chisel3 - Tutorial - Functionality

    https://mp.weixin.qq.com/s/3hDzpJiANdwp07hO03psyA   演示使用函数进行代码复用的方法.   参考链接: https://github.com/ucb- ...

  6. 【Hadoop】Hadoop的安装,本地模式、伪分布模式的配置

    Download hadoop-2.7.7.tar.gz 下载稳定版本的hadoop-2.7.7.tar.gz(我用的2.6.0,但是官网只能下载2.7.7的了) Required Software ...

  7. Maven+JSP+SSM+Mysql实现的音乐网站

    项目简介 项目来源于:https://gitee.com/coder_ze/iMusic 本系统基于Maven+JSP+SSM+Mysql实现的音乐网站.主要实现的功能有音乐播放.下载.上传等几个模块 ...

  8. (三)用less+gulp+requireJs 搭建项目(requireJs)

    首先我想说下我在写js时经常遇到的问题,尤其是很大的项目: 1.我一般会把各个功能分块写在各个js文件中: 比如弹出框: dialog.js $(document).ready(function(){ ...

  9. Java实现 LeetCode 147 对链表进行插入排序

    147. 对链表进行插入排序 对链表进行插入排序. 插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将 ...

  10. Java实现第九届蓝桥杯方格计数

    方格计数 题目描述 如图p1.png所示,在二维平面上有无数个1x1的小方格. 我们以某个小方格的一个顶点为圆心画一个半径为1000的圆. 你能计算出这个圆里有多少个完整的小方格吗? 注意:需要提交的 ...