博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用递归和回溯法实现八皇后问题
阅读量:5875 次
发布时间:2019-06-19

本文共 2919 字,大约阅读时间需要 9 分钟。

   问题描述:

  八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋棋盘上放置八个皇后,使得任意两个皇后不能互相攻击,即任何行、列或对角线(与水平轴夹角为45°或135°的斜线)上不得有两个或两个以上的皇后。对于这个问题数学家高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。 问题分析      在这里我们可以声明一个8行8列的数组来模拟国际象棋的棋盘,然后,给数组初始化为字符 '*',来表示棋盘上没有放置皇后的状态,用'#' 表示皇后。这样数组中的每个元素都可以表示棋盘的状态,即   # :表示有皇后   * :表示没有皇后   创建一个函数用于实现递归的调用,在这里我们声明为void SearchEightQueue(int i); 具体设计思路如下:   对棋盘一行一行地进行扫描,如果发现可以放置皇后的位置则把代表此位置状态的元素赋值为'#',然后继续扫描下一行,如果一直扫描到第八行仍然可以找到放置皇后的位置,说明这种摆法是正确的,把棋盘打印出来。如果发现当进行到某一行时无法找到可以放皇后的位置,那么则回溯到初始状态。 代码如下:
/*八皇后问题,#代表皇后位置*/#include 
#include
static int EightQueueNum = 0;//定义一个全局静态变量EightQueueNum,以便打印出总的方案数目static char Queue[8][8];//定义一个8行8列的棋盘static int a[8];//定义一行中各个列的状态,a[0]~a[7]分别表示第一列到第八列,如果a[1]=1,说明这列存在皇后static int b[15];static int c[15];void SearchEightQueue(int i){ int iColumn,iLine,iColumn1; for(iColumn = 0;iColumn < 8;iColumn++) { if(a[iColumn] == 0 && b[i+iColumn] == 0 && c[i-iColumn+7] == 0) { Queue[i][iColumn] = '#'; a[iColumn] = 1; b[i+iColumn] = 1; c[i-iColumn+7] = 1; if(i < 7) SearchEightQueue(i+1); else { EightQueueNum++; printf("\n八皇后问题的第%d种解决方案为:\n",EightQueueNum); for(iLine = 0;iLine < 8;iLine++) { for(iColumn1 = 0;iColumn1 < 8;iColumn1++) { printf("%c ",Queue[iLine][iColumn1]); } printf("\n"); } if(EightQueueNum%10 == 0) { getch(); } } /* 如果程序未成功扫描到第7行就发现没有位置可以放我们的皇后了,这样我们回溯到原来的状态重新扫描 即如果我们i= 3时满足if(a[iColumn] == 0 && b[i+iColumn] == 0 && c[i-iColumn+7] == 0)语句进入 了循环,但是当i+1变成4时不满足if(a[iColumn] == 0 && b[i+iColumn] == 0 && c[i-iColumn+7] == 0) 语句了这样这个摆放顺序就不正确,需要我们把之前从i=0到i=3(第一行到第四行)时放置的皇后取消掉, 利用递归调用函数的顺序,刚好可以实现。这样当SearchEightQueue()函数执行完成后,矩阵Queue[8][8] 中的状态刚好跟定义时候的状态是一致的。就这样一直一直的尝试,直到所有的状态都被尝试过(其中正确 的结果打印出来,是正确结果就说明当i = 7时,仍然满足 if(a[iColumn] == 0 && b[i+iColumn] == 0 && c[i-iColumn+7] == 0))进入了循环,并且i= 7,进入到了 else语句块。 */ Queue[i][iColumn] = '*'; a[iColumn] = 0; b[i+iColumn] = 0; c[i-iColumn+7] = 0; } }}int main(){ int i = 0,j; for( i = 0;i < 8;i++) { a[i] = 0; for(j = 0;j < 8;j++) { Queue[i][j] = '*'; } printf("\n"); } for( i = 0;i < 16;i++) { b[i] = 0; c[i] = 0; } SearchEightQueue(0); printf("总共的解决方案为: %d",EightQueueNum); return 0;}

  

  
posted on
2014-12-16 17:14 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/devinblog/p/4167572.html

你可能感兴趣的文章
python活用isdigit方法显示系统进程
查看>>
项目开发总结
查看>>
知行合一
查看>>
jmeter插件之jsonpath提取响应结果和做断言
查看>>
apt-get 命令加 autoclean clean autoremove 区别
查看>>
Docs-->.NET-->API reference-->System.Web.UI.WebControls-->Repeater
查看>>
发布支持多线程的PowerShell模块 —— MultiThreadTaskRunner
查看>>
Ubuntu ctrl+alt会导致窗口还原的问题
查看>>
第四十期百度技术沙龙笔记整理
查看>>
推荐系统那点事 —— 基于Spark MLlib的特征选择
查看>>
linux 下RTL8723/RTL8188调试记录(命令行)【转】
查看>>
開始新的征程
查看>>
SpringMVC案例1——对User表进行CRUD操作
查看>>
看雪CTF第十四题
查看>>
模拟生命_吸烟致癌?
查看>>
[Contiki系列论文之1]Contiki——为微传感器网络而生的轻量级的、灵活的操作系统...
查看>>
Android 网络编程 记录
查看>>
微软同步发行Windows 10和Windows 10 Mobile系统更新
查看>>
Maven 传递依赖冲突解决(了解)
查看>>
Zeppelin的入门使用系列之使用Zeppelin运行shell命令(二)
查看>>