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.代码实现

    public class EightQueens
{
//定义一个max表示共有多少个皇后
static int _max = ; //定义数组arr,保存皇后放置位置的结果,比如 arr={0,4,7,5,2,6,1,3}
static int[] _arr = new int[_max]; //初始化解法次数
static int _count = ; //初始化冲突次数
static int _judgeCount = ;
public static void Test()
{
EightQueens.Check(); Console.WriteLine($"一共有{_count}种解法"); Console.WriteLine($"一共判断冲突的次数{_judgeCount}次");
} /// <summary>
///编写一个方法,放置第n个皇后
///Check是每一次递归时,进入到Check中都有for(int i=0;i<_max;i++),因此会有回溯
/// </summary>
/// <param name="n"></param>
private static void Check(int n)
{
if (n == _max) //当n=8,说明8个皇后已经方法,因为初始值从0开始
{
Print(); return;
} //依次放入皇后,并判断是否有冲突
for (int i = ; i < _max; i++)
{
//先把当前这个皇后n,放到该行的第1列
_arr[n] = i; //判断当放置第n个皇后到i列时,是否冲突
if (Judge(n))
{
//如果不冲突,接着放n+1个皇后,即开始递归
Check(n + );
} //如果冲突,就继续执行arr[n]=i,即将第n个皇后,放置在本行的后移的一个位置
}
} /// <summary>
/// 查看当我们放置第n个皇后,就去检查该皇后是否和前面已经判断的皇后冲突
/// </summary>
/// <param name="n">表示第n个皇后</param>
/// <returns></returns>
private static bool Judge(int n)
{
_judgeCount++; for (int i = ; i < n; i++)
{
//1._arr[i] == _arr[n] 表示判断第n个皇后,是否和前面的n-1个皇后在同一列
//2.Math.Abs(n - i) == Math.Abs(_arr[n] - _arr[i])表示判断第n个皇后是否和第i个皇后在同一个斜线
//取个例子:当 n=1的时候 也就是放置第2列 Math.Abs(1-0)==Math.Abs(1-0)=1
//3.判断是否在同一行,没有必要,n每次都在递增
if (_arr[i] == _arr[n] || Math.Abs(n - i) == Math.Abs(_arr[n] - _arr[i]))
{
return false;
}
} return true;
} /// <summary>
/// 皇后的摆放位置输出
/// </summary>
private static void Print()
{
_count++; for (int i = ; i < _arr.Length; i++)
{
System.Console.Write(_arr[i] + " ");
} System.Console.WriteLine();
}
}

5.结果图


一共有92种解法
一共判断冲突的次数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. Rocket - spec - RISC-V规范整理

    https://mp.weixin.qq.com/s/xP8JRhkmgUQf0QRm3S2mjA   根据RISC-V规范整理的几个文档.   ​​     1. 原文链接 https://risc ...

  2. Chisel3 - Tutorial - VendingMachineSwitch

    https://mp.weixin.qq.com/s/5lcMkenM2zTy-pYOXfRjyA   演示如何使用switch/is来实现状态机.   参考链接: https://github.co ...

  3. float:left的妙用

    在html页面中,我们总是会遇到这样的情况: 当然,这是比较简单的情况,用ul内包li就可以, <ul> <li><img src="logo.jpg" ...

  4. 【Storm】核心组件nimbus、supervisor、worker、executor、task

    nimbus 是整个集群的控管核心,负责topology的提交.运行状态监控.任务重新分配等工作. zk就是一个管理者,监控者. 总体描述:nimbus下命令(分配任务),zk监督执行(心跳监控wor ...

  5. Java实现 LeetCode 740 删除与获得点数(递推 || 动态规划?打家劫舍Ⅳ)

    740. 删除与获得点数 给定一个整数数组 nums ,你可以对它进行一些操作. 每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数.之后,你必须删除每个等于 nums[ ...

  6. Java实现 LeetCode 738 单调递增的数字(暴力)

    738. 单调递增的数字 给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增. (当且仅当每个相邻位数上的数字 x 和 y 满足 x <= ...

  7. Java实现 LeetCode 622 设计循环队列(暴力大法)

    622. 设计循环队列 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器" ...

  8. Java实现 LeetCode 495 提莫攻击

    495. 提莫攻击 在<英雄联盟>的世界中,有一个叫 "提莫" 的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态.现在,给出提莫对艾希的攻击时间序列和 ...

  9. Java实现 蓝桥杯VIP 算法训练 筛选号码

    算法训练 筛选号码 Description 有n个人围成一圈,顺序排号(编号为1到n).从第1个人开始报数(从1到3报数),凡报到3的人退出圈子.从下一个人开始继续报数,直到剩下最后一个人,游戏结束. ...

  10. Java实现 蓝桥杯VIP 算法提高 插入排序

    算法提高 插入排序 时间限制:1.0s 内存限制:256.0MB  插入排序 问题描述 排序,顾名思义,是将若干个元素按其大小关系排出一个顺序.形式化描述如下:有n个元素a[1],a[2],-,a[ ...