八皇后问题
Posted darkvalkyrie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八皇后问题相关的知识,希望对你有一定的参考价值。
1213:八皇后问题
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 5367 通过数: 1856
【题目描述】
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
【输入】
(无)
【输出】
按给定顺序和格式输出所有八皇后问题的解(见样例)。
【输入样例】
(无)
【输出样例】
No. 1 1 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. 2 1 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<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define N 100 using 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 ",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<<endl; } } return 0; }
2019-02-05 20:59:02
以上是关于八皇后问题的主要内容,如果未能解决你的问题,请参考以下文章