回溯算法-C#语言解决八皇后问题的写法与优化
结合问题说方案,首先先说问题:
八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
嗯,这个问题已经被使用各种语言解答一万遍了,大多还是回溯法解决的。
关于回溯算法:个人理解为就是优化的穷举算法,穷举算法是指列出所有的可能情况,而回溯算法则是试探发现问题"剪枝"回退到上个节点,换一条路,能够大大提高求解效率。
具体到8皇后问题上来说,需要考虑以下几点:
1)将8个皇后定义为8行中的相对位置来标识,考虑增加新的皇后时,是否与之前的皇后位置冲突(即可以攻击之前摆放的皇后:位置相等或者斜率1or-1)
2)新放的皇后发生冲突时回溯至上一行继续试探,逐步回溯直至第一行为止
3)已经求出的解再次探索时避免重复
4)从第一行开始放皇后,然后开始循环往下放,可以设计为回调放皇后的方法
说了这么多废话,开始写吧,啪啪啪-- 12秒过去了,写完了,运行-----嘛结果也没有!!
贴上代码及注释
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Queen
{
class Program
{
//定义解的个数
int sum = 0;
//定义皇后数组
int[] Queens = new int[8];
static void Main(string[] args)
{
Program Pro = new Program();
//开始求解
Pro.QueenSort(0);
}
//排序获取组合(1-8)
public void QueenSort(int num)
{ for (int j = 1; j < 9; j++)
{
if (num == 8)
{
sum++;
//打印输出
Write();
break;
}
Queens[num] = j;
//判断是否冲突
if (FooConflict(num, j))
{
num++;
QueenSort(num);
}
}
} /// <summary>
/// 判断皇后是否和之前所有的皇后冲突
/// </summary>
/// <param name="row">已放置完毕无冲突皇后的列数</param>
/// <param name="queen">新放置的皇后值</param>
/// <returns>是否冲突</returns>
public bool FooConflict(int row, int queen)
{
if (row == 0)
{
return true;
}
else
{
//循环判断与之前的皇后是否有冲突的
for (int pionter = 0; pionter < row; pionter++)
{
//如果有,返回false
if (!FooCompare(Queens[pionter], row - pionter, queen))
{
return false;
}
}
//与之前均无冲突,返回true
return true;
}
}
/// <summary>
/// 对比2个皇后是否冲突
/// </summary>
/// <param name="i">之前的一个皇后</param>
/// <param name="row">2个皇后的列数之差</param>
/// <param name="queen">新放置的皇后</param>
/// <returns></returns>
public bool FooCompare(int i, int row, int queen)
{
//判断2个皇后是否相等或者相差等于列数之差(即处于正反对角线)
if ((i == queen) || ((i - queen) == row) || ((queen - i) == row))
{
return false;
}
return true;
}
//打印皇后图案
public void Write()
{
//输出皇后的个数排序
Console.WriteLine("第{0}个皇后排列:", sum);
for (int i = 0; i < 8; i++)
{
for (int j = 1; j < 9; j++)
{
if (j == Queens[i])
{
Console.Write("■");
}
else
{
Console.Write("□");
}
}
//换行
Console.Write("\n");
}
}
}
}
PS:还好我写的方法分的很细,直接锁定QueenSort()这个方法,嗯,一定是它出了问题!
仔细一看num++这一行,本意是循环QueenSort(num+1)查询下一个皇后的解,这样写导致下次循环赋值Queens[num]出现了异常,果断改了,运行OK!
贴上代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Queen
{
class Program
{
//定义解的个数
int sum = 0;
//定义皇后数组
int[] Queens = new int[8];
static void Main(string[] args)
{
Program Pro = new Program();
//开始求解
Pro.QueenSort(0);
}
//排序获取组合(1-8)
public void QueenSort(int num)
{
for (int j = 1; j < 9; j++)
{
if (num == 8)
{
sum++;
//打印输出
Write();
break;
}
//判断是否冲突
if (FooConflict(num, j))
{
Queens[num] = j;
QueenSort(num+1);
}
}
} /// <summary>
/// 判断皇后是否和之前所有的皇后冲突
/// </summary>
/// <param name="row">已放置完毕无冲突皇后的列数</param>
/// <param name="queen">新放置的皇后值</param>
/// <returns>是否冲突</returns>
public bool FooConflict(int row, int queen)
{
if (row == 0)
{
return true;
}
else
{
//循环判断与之前的皇后是否有冲突的
for (int pionter = 0; pionter < row; pionter++)
{
//如果有,返回false
if (!FooCompare(Queens[pionter], row - pionter, queen))
{
return false;
}
}
//与之前均无冲突,返回true
return true;
}
}
/// <summary>
/// 对比2个皇后是否冲突
/// </summary>
/// <param name="i">之前的一个皇后</param>
/// <param name="row">2个皇后的列数之差</param>
/// <param name="queen">新放置的皇后</param>
/// <returns></returns>
public bool FooCompare(int i, int row, int queen)
{
//判断2个皇后是否相等或者相差等于列数之差(即处于正反对角线)
if ((i == queen) || ((i - queen) == row) || ((queen - i) == row))
{
return false;
}
return true;
}
//打印皇后图案
public void Write()
{
//输出皇后的个数排序
Console.WriteLine("第{0}个皇后排列:", sum);
for (int i = 0; i < 8; i++)
{
for (int j = 1; j < 9; j++)
{
if (j == Queens[i])
{
Console.Write("■");
}
else
{
Console.Write("□");
}
}
//换行
Console.Write("\n");
}
}
}
}
运行结果如下图:

OK! 等等 为毛百度了一下C语言的实现只有几行!! 不过想想咱们的核心代码排序方法也就几行,还行吧,以后有空再考虑优化下
that’s all !
回溯算法-C#语言解决八皇后问题的写法与优化的更多相关文章
- C语言解决八皇后问题
#include <stdio.h> #include <stdlib.h> /* this code is used to cope with the problem of ...
- 使用穷举法结合numpy解决八皇后问题
一般说到八皇后问题,最先想到的就是回溯思想,而回溯思想往往是需要递归来实现的. 计算机很善长做重复的事情,所以递归正和它的胃口,而我们人脑更喜观平铺直叙的思维方式.当 我们看到递归时,总想把递归平铺展 ...
- Python解决八皇后问题
最近看Python看得都不用tab键了,哈哈.今天看了一个经典问题--八皇后问题,说实话,以前学C.C++的时候有这个问题,但是当时不爱学,没搞会,后来算法课上又碰到,只是学会了思想,应该是学回溯法的 ...
- Python 解决八皇后问题
问题介绍 八皇后问题是一个以国际象棋为背景的问题:如何能够在 \(8\times8\) 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一 ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...
- LeetCode 回溯法 别人的小结 八皇后 递归
#include <iostream> #include <algorithm> #include <iterator> #include <vector&g ...
- Python解决八皇后问题的代码【解读】
八皇后问题 来自于西方象棋(现在叫 国际象棋,英文chess),详情可见百度百科. 在西方象棋中,有一种叫做皇后的棋子,在棋盘上,如果双方的皇后在同一行.同一列或同一斜线上,就会互相攻击. 八皇后问题 ...
- 使用java语言实现八皇后问题
八皇后问题,在一个8X8的棋盘中,放置八个棋子,每个棋子的上下左右,左上左下,右上右下方向上不得有其他棋子.正确答案为92中,接下来用java语言实现. 解: package eightQuen; / ...
- C语言:试探算法解决“八皇后”问题
#include <stdio.h> #define N 4 int solution[N], j, k, count, sols; int place(int row, int col) ...
随机推荐
- SPRING+JNDI+C3P0 in tomcat6
Tomcat 中Jndi是使用Tomcat自带的连接池,由于客户要求,抛弃Tomcat自带的连接池.使用c3p0 .经过几个小时调试,解决方案如下: 环境:Tomcat 6 下面来看Jndi 与 c3 ...
- JQuery 选择器 *很重要 多记
1)基本选择器: 跟CSS选择器类似 2) 层次选择器 div>span 紧接这div同一级下的全部span .one+div 同一等级的div #two~div 同一等级di ...
- Handsontable Read-only cells
一,列只读
- SPRING源码分析:IOC容器
在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...
- 基于avalon1.4.x ----分页组件编写
avalon分页组件 (1.4.x版本) 随着avalon2的推出,avalon1的官网已经不再维护了,现在似乎是找不到avalon 1.4版本的官方文档了,所以本文章所有的内容均不保证正确性,只能保 ...
- jquery插件datepicker
jQuery UI很强大,其中的日期选择插件Datepicker是一个配置灵活的插件,我们可以自定义其展示方式,包括日期格式.语言.限制选择日期范围.添加相关按钮以及其它导航等. <script ...
- 在本地调试微信项目(C#)
之前一人负责微信的项目,那时2014年LZ还没毕业..啥都不懂,为此特别感谢@SZW,没有你的框架,我可能都无从下手 当时做项目最麻烦的就是调试,因为很多页面都要使用 网页授权获取用户信息 在电脑上打 ...
- Android SQLite的使用2(非原创)
1.数据库的增.删.改.查:execSQL方法 public void insertAction() {//添加信息 db.execSQL("insert into Emp(name,sal ...
- 对list代理扩展功能
package 动态代理扩展List; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; imp ...
- (转)Java程序利用main函数中args参数实现参数的传递
Java程序利用main函数中args参数实现参数的传递 1.运行Java程序的同时,可以通过输入参数给main函数中的接收参数数组args[],供程序内部使用!即当你在Java命令行后面带上参数,J ...