结合问题说方案,首先先说问题:

八皇后问题:在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#语言解决八皇后问题的写法与优化的更多相关文章

  1. C语言解决八皇后问题

    #include <stdio.h> #include <stdlib.h> /* this code is used to cope with the problem of ...

  2. 使用穷举法结合numpy解决八皇后问题

    一般说到八皇后问题,最先想到的就是回溯思想,而回溯思想往往是需要递归来实现的. 计算机很善长做重复的事情,所以递归正和它的胃口,而我们人脑更喜观平铺直叙的思维方式.当 我们看到递归时,总想把递归平铺展 ...

  3. Python解决八皇后问题

    最近看Python看得都不用tab键了,哈哈.今天看了一个经典问题--八皇后问题,说实话,以前学C.C++的时候有这个问题,但是当时不爱学,没搞会,后来算法课上又碰到,只是学会了思想,应该是学回溯法的 ...

  4. Python 解决八皇后问题

    问题介绍 八皇后问题是一个以国际象棋为背景的问题:如何能够在 \(8\times8\) 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一 ...

  5. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  6. LeetCode 回溯法 别人的小结 八皇后 递归

    #include <iostream> #include <algorithm> #include <iterator> #include <vector&g ...

  7. Python解决八皇后问题的代码【解读】

    八皇后问题 来自于西方象棋(现在叫 国际象棋,英文chess),详情可见百度百科. 在西方象棋中,有一种叫做皇后的棋子,在棋盘上,如果双方的皇后在同一行.同一列或同一斜线上,就会互相攻击. 八皇后问题 ...

  8. 使用java语言实现八皇后问题

    八皇后问题,在一个8X8的棋盘中,放置八个棋子,每个棋子的上下左右,左上左下,右上右下方向上不得有其他棋子.正确答案为92中,接下来用java语言实现. 解: package eightQuen; / ...

  9. C语言:试探算法解决“八皇后”问题

    #include <stdio.h> #define N 4 int solution[N], j, k, count, sols; int place(int row, int col) ...

随机推荐

  1. dp优化

    入口 A(fzu 1894) 普通的单调队列,trick是进队判断的符号选取(>=wa , >ac). B(poj 2823) 没什么好说的 ,坑爹poj g++,tle ;c++,ac. ...

  2. 04747_Java语言程序设计(一)_第9章_输入和输出流

    例9.1一个文件复制应用程序,将某个文件的内容全部复制到另一个文件. import java.io.*; public class Example9_1 { public static void ma ...

  3. Python开发过程中17个坑

    一.不要使用可变对象作为函数默认值 复制代码代码如下: In [1]: def append_to_list(value, def_list=[]):   ...:         def_list. ...

  4. android jni ——Field & Method --> Accessing Field

    现在我们知道了怎样使用native code访问简单的数据类型和引用参考类型(string,array),下面我们来介绍怎样让jni代码去访问java中的成员变量和成员函数,然后可以再jni中回调ja ...

  5. C++: int和string相互转换

    假设在一个C++的程序中常常会用到int和string之间的互换.个人建议能够写成一个函数,下次用的时候直接调用就可以. #include <iostream> #include < ...

  6. mybatis于Date和DateTime现场插入

    最近,该公司使用MyBatis3做数据持久层,有在该领域Date和DateTime种类,只有在插入数据时属性设置为一个实体Timestamp将相应mysql的DateTime类型.Date会相应mys ...

  7. 连数据库是ODBC好还是OLEDB好

    1.连数据库是ODBC好还是OLEDB好?2.是不是只有微软的数据库才可以用OLEDB?3.要切换这两种连接,是不是只需要修改连接字符串?谢谢大家了,小弟对这三个问题不解 分享到:   2009-03 ...

  8. Oracle—RMAN备份(二)

    在Oracle  RMAN备份(一)中,对各种文件在RMAN中备份进行了说明, 一.备份集的复制 在RMAN 备份中,可以备份其自己的备份,即备份一个文件放在多个目录下,oralce支持最多备份四个. ...

  9. 22. 使用 awk / grep / head / tail 命令进行文本 / 日志分析 (/home/D/acc.log)

    一.awk     # 统计 a-read-file 接口 中,接口耗时 超过 0.007 秒的有多少个请求     D@Demon ~]$ awk '$7>0.007' acc.log | w ...

  10. 调试Linq的时候获得相对应的SQL

    (query as System.Data.Objects.ObjectQuery).ToTraceString()