博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
八皇后问题
阅读量:5360 次
发布时间:2019-06-15

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

1213:八皇后问题

时间限制: 1000 ms         内存限制: 65536 KB
提交数: 5367     通过数: 1856 

【题目描述】

在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。

【输入】

(无)

【输出】

按给定顺序和格式输出所有八皇后问题的解(见样例)。

【输入样例】

(无)

【输出样例】

No. 11 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 No. 21 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ...以下省略 例题不怎么详的解: 简介: 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。 1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。 国际象棋中,皇后可以横斜直三个方向走,步数不受限制,是最强的棋子。 放在本题中考虑,粗略分析,在8*8的棋盘中,要放下八个皇后,每个皇后一定异行异列,才能满足题目要求。 经过以上分析,很明显,每两个皇后之间的位置关系是(用i表示行,j表示列): ai≠bi,aj≠bj(不同行列),|ai-bi|≠|aj-bj|,|ai+bi|≠|aj+bj|(不同斜线); 即不同行不同列不同斜线。 好的,基本思路很简单,接下来是算法实现。别看思路简单,其实这是一道经典的难题。

算法分析: 这是一个有点dp的搜索算法。呃。。。回溯算法。 初步思路是设置一个int型一维数组储存皇后的位置; 接下来,就是完成搜索函数的功能了。 逐行放置棋子,同时检查是否符合两棋子之间的条件关系,直到放完8个棋子。 但是我们如何判断两个皇后之间的关系呢?这里是本题的关键。 这里有一种便捷的方法,因为根据算法每个棋子必定异行,那就设置3个数组,表达某处被占地整列,整左斜线,整右斜线上的格子不得放置下一枚棋子。 为方便起见,我们设置一个关键二维数组vis[3][(此处应大于16,因为最值为i+j=16)]. 首先检查当前列,行,斜线上能否放置:
if(vis[0][i]==0&&vis[1][step+i]==0&&vis[2][step-i+8]==0)//注意:vis[2]由于数组会越界,在行列值相减后必须加至大于0;
如果是,放置棋子,并声明棋子所在行,列,斜线全部无法放置棋子:
vis[0][i]=1;vis[1][i+step]=1;vis[2][step-i+8]=1; a[step]=i;

    接下来,搜索下一颗棋子:

dfs(step+1);

   完事了以后要销毁证据/滑稽(回溯):

vis[0][i]=0;vis[1][i+step]=0;vis[2][step-i+8]=0;

   肥肠好,到这里搜索部分就基本完成了。

   加入递归边界:

if(step==9)    {        tot++;        for(int i=1;i<=8;i++)            ans[tot][i]=a[i];//设置传值数组,将所有临时数据传入此数组。        return;    }

 大功告成!

   说实话挺简单的,但是我怎么写都是错的,最后还是去看了一眼答案。。。虽说思路一样吧。。。但是为什么我就是错了(蓝瘦)??? 

   没什么需要具体分析的。

   样例代码:

#include
#include
#include
#include
#define N 100using namespace std;int ans[N][N],a[N];int vis[N][N];int tot;void dfs(int step){ if(step==8+1) { tot++; for(int i=1;i<=8;i++) ans[tot][i]=a[i]; return; } for(int i=1;i<=8;i++) { if(vis[0][i]==0&&vis[1][step+i]==0&&vis[2][step-i+8]==0) { vis[0][i]=1; vis[1][i+step]=1; vis[2][step-i+8]=1; a[step]=i; dfs(step+1); vis[0][i]=0; vis[1][i+step]=0; vis[2][step-i+8]=0; } }}int main(){ dfs(1); for(int t=1;t<=tot;t++) { printf("No. %d\n",t); for(int i=1;i<=8;i++) { for(int j=1;j<=8;j++) { if(ans[t][j]==i) cout<<"1 "; else cout<<"0 "; } cout<

2019-02-05 20:59:02

 

转载于:https://www.cnblogs.com/DarkValkyrie/p/10353129.html

你可能感兴趣的文章
day22 Python shelve模块
查看>>
Win10 收件箱添加QQ邮箱(2019年5月19日)
查看>>
Java知多少(97)绘图模式概述
查看>>
C#.NET如何不序列化字段、属性
查看>>
Android JNI和NDK学习(02)--静态方式实现JNI(转)
查看>>
在libuv中使用openssl建立ssl连接(转)
查看>>
常见的CSS浏览器兼容问题
查看>>
Android动画的理解
查看>>
JavaWeb学习篇之----EL表达式详解
查看>>
数组去重的方法
查看>>
solaris下的目录ls不到,却能cd进去
查看>>
rhel 6 启动流程分析(/etc/inittab)
查看>>
hdu 4871 树的分治+最短路记录路径
查看>>
java基础 第三章 下(方法)
查看>>
网站上如何添加显示favicon
查看>>
BFS和DFS记录路径
查看>>
【HDOJ】4642 Fliping game
查看>>
2016腾讯春季实习生招聘软件测试开发岗位笔试题
查看>>
No.1一步步学习vuejs 环境配置安装篇
查看>>
Springboot读取Request参数的坑
查看>>