1.“八皇后”问题

八皇后问题是十九世纪著名数学家高斯于1850年提出的。问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同一行,同一列,或同一斜线上。可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。

2.冲突条件判断

如下图,方块内的值(i,j)表示第i行第j列。(1,1)位置如果放了皇后,那么(1,1)位置所在的行,列,斜线上都不能再放皇后。

如何判断两个位置冲突呢?

(1)判断两个位置是否再斜线上:根据斜率

A(1,1)位置,B(2,0)位置和C(2,2)位置,A和B冲突:(0-1)/(2-1)==-1,A和C冲突:(2-1)/(2-1)==1。

因此,对于任意两点A(x1,y1)和B(x2,y2),两点斜线冲突满足条件:abs((y2-y1)/(x2-x1))==1,

该公式转换为:abs(y2-y1)== abs(x2-x1)

(2)判断两个位置是否在同一列/同一行

任意两点A(x1,y1)和B(x2,y2)在同一列满足条件:y1 == y2,在同一行满足条件:x1 == x2


判断冲突代码如下:

int valid(int row, int col)    //判断第row行第col列是否可以放置皇后
{int i;for (i = 0; i < QUEEN; ++i)  //对已得到的解搜索,看是否冲突{   //判断列冲突与斜线上的冲突//表示第i行第col列放了皇后,(row - i) / (col - arr[i]) != 1 或 -1// arr[i] = k表示第i行第k列放了皇后if (a[i] == col || abs(i - row) == abs(a[i] - col))return 0;}return 1;
}

3.进入正题--回溯法解决

(1)初始化棋盘

#define INITIAL -10000 //棋盘的初始值const int QUEEN = 8;int a[QUEEN];//表示解空间a[1]=2表示[1,2]位置有皇后
void init()//初始化
{int *p;for(p=a;p<a+QUEEN;++p)*p = INITIAL;
}

(2)非递归回溯

void queen()      //N皇后程序
{int n = 0;int i = 0, j = 0;//i表示行,j表示每行的列while (i < QUEEN)//满足继续搜索的条件
    {///没有到叶子结点情况下就继续搜索while (j < QUEEN)        //对i行的每一列进行探测,看是否可以放置皇后
        {if(valid(i, j))      //该位置可以放置皇后
            {a[i] = j;        //第i行放置皇后,位置位j列j = 0;           //第i行放置皇后以后,需要继续探测下一行的皇后位置,//所以此处将j清零,从下一行的第0列开始逐列探测break;}else{++j;             //继续探测下一列
            }}///搜索到了叶子结点但是无解,直接回溯到上一行if(a[i] == INITIAL)         //第i行没有找到可以放置皇后的位置
        {if (i == 0)             //回溯到第一行,仍然无法找到可以放置皇后的位置,//则说明已经找到所有的解,程序终止break;else                    //没有找到可以放置皇后的列,此时就应该回溯
            {--i;j = a[i] + 1;        //把上一行皇后的位置往后移一列a[i] = INITIAL;      //把上一行皇后的位置清除,重新探测continue;}}//找到解if (i == QUEEN - 1)          //最后一行找到了一个皇后位置,//说明找到一个结果,打印出来
        {printf("answer %d : \n", ++n);print();//不能在此处结束程序,因为我们要找的是N皇后问题的所有解,//此时应该清除该行的皇后,从当前放置皇后列数的下一列继续探测。j = a[i] + 1;             //从最后一行放置皇后列数的下一列继续探测a[i] = INITIAL;           //清除最后一行的皇后位置continue;}++i;              //继续探测下一行的皇后位置
    }
}

(3)结果打印

void print()    //打印输出N皇后的一组解
{int i, j;for (i = 0; i < QUEEN; ++i){for (j = 0; j < QUEEN; ++j){if (a[i] != j)      //a[i]为初始值printf("%c ", '.');else                //a[i]表示在第i行的第a[i]列可以放置皇后printf("%c ", '#');}printf("\n");}for (i = 0; i < QUEEN; ++i)printf("%d ", a[i]);printf("\n");printf("--------------------------------\n");
}

转载于:https://www.cnblogs.com/jainszhang/p/10701661.html

回溯法解决八皇后问题相关推荐

  1. 七十八、 回溯法解决八皇后问题

    @Author:Runsen 八皇后问题 八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后. 来自百度百科,皇后的走法是可 ...

  2. 回溯法(八皇后问题)及C语言实现

    回溯法,又被称为"试探法".解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择.这种走不通就回退再走的 ...

  3. 回溯算法解决八皇后_4皇后问题和使用回溯算法的解决方案

    回溯算法解决八皇后 4-皇后问题 (4 - Queen's problem) In 4- queens problem, we have 4 queens to be placed on a 4*4 ...

  4. 栈(Stack)的应用—试探回溯法:八皇后问题、迷宫寻径

    栈的应用 试探回溯法 1.八皇后问题 皇后类 struct Queen { //皇后类int x, y; //坐标Queen (int xx = 0, int yy = 0 ) : x(xx), y( ...

  5. 回溯法解决n皇后问题

    回溯法解决n皇后问题 题目要求: 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于在n×n格的棋盘上放置n个皇后, ...

  6. 【回溯法】八皇后问题

    问题描述 在国际象棋棋盘(8×8)(8\times8)(8×8)上放置八个皇后,要求每两个皇后之间不能直接吃掉对方. 皇后可以攻击处于同一行.同一列和同一对角线上的棋子. 思路分析 八皇后问题可以使用 ...

  7. Java实现递归回溯,解决八皇后问题,数据结构与算法

    文章目录 八皇后问题 解决思路 代码实现 运行结果 八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆 ...

  8. 回溯算法解决八皇后问题(JAVA实现)

    送给程序猿们一句话 <拥有水滴石穿的坚持:懂得聚沙成塔的积累:磨练坚韧不拔的意志:学习脚踏实地的奋斗:提升立世做人的技巧:突破自我设限的障碍.> 文章目录 背景 问题解决 思路 什么是回溯 ...

  9. 用递归思想和回溯算法解决八皇后问题(java实现)

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

  10. 回溯法解决N皇后问题——递归与非递归求解

    回溯法其实也是一种搜索算法,它可以方便的搜索解空间.  回溯法解题通常可以从以下三步入手:  1.针对问题,定义解空间  2.确定易于搜索的解空间结构  3.以深度优先的方式搜索解空间,并在搜索的过程 ...

最新文章

  1. 最近,又一家互联网公司裁员了,失业来得太突然…
  2. 如何让VB6代码编辑器垂直滚动条随鼠标滚轮滚动
  3. 因为你组织的安全策略阻止未经身份验证的来宾(试了很多种办法都不行)
  4. Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)
  5. 使用多行sql字符串时,要注意不要忽略了空格
  6. Linux系统可卸载内核模块完全指南(上)
  7. html军事学校模板,军事训练学校网站模板
  8. could not connect to smtp host java_服务器发送邮件出现Could not connect to SMTP host错误 解决办法...
  9. 常用软件分类 精选列表(二)
  10. canvas中手动绘制椭圆的方法
  11. Blue Screen Of Death ( BSOD ) 错误信息解析解释
  12. 操作系统之文件管理思维导图
  13. 为什么那些美事没有实现---生活中小事有感
  14. Linux常用命令——jwhois命令
  15. 七天学会NodeJS (原生NodeJS 学习资料 来自淘宝技术团队)
  16. 5.8 使用轮廓化描边命令制作心形艺术图标 [Illustrator CC教程]
  17. html 游戏 调用震动,html5消息和震动api
  18. Unity 报错TLS Allocator ALLOC_TEMP_THREAD, underlying allocator ALLOC_TEMP_THREAD
  19. badminton ball
  20. PHP - 设计模式系列

热门文章

  1. Cocos2d-x物理引擎概述
  2. KVM详解(三)——KVM创建虚拟机
  3. Tomcat详解(四)——Tomcat配置详解
  4. Bugku杂项小猪佩奇思路
  5. 如何使用Secure CRT连接到华三模拟器上和华为模拟器上(更新模拟器版本,SecureCRT版本)
  6. leetcode 20. 有效的括号 (python)
  7. 24. Swap Nodes in Pairs 1
  8. PTA(BasicLevel)-1009 说反话
  9. mysql 按类型查询个数和总数
  10. 【Lolttery】项目开发日志 (七)socket io 结合 react js实现简单聊天室