深度优先搜索问题--八皇后(洛谷1219)题解

深度优先搜索问题--八皇后 题解


题目描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

深度优先搜索问题--八皇后(洛谷1219)题解_第1张图片
上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:

行号 1 2 3 4 5 6

列号 2 4 6 1 3 5

这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。

//以下的话来自usaco官方,不代表洛谷观点

特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号删除并且不能参加USACO的任何竞赛。我警告过你了!

输入格式
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。

输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

以下是代码:

#include
#include
using namespace std;
int n;  //n用来表示棋盘大小(n x n)
int sum=0;  //sum用来记录满足题意的解的和
int ans=0;  //ans用来限制输出解的个数,只能输出前三个数
int a[20],b[30],c[30],d[20];  //a数组表示棋盘中的列;b数组表示左下—右上的对角线;c数组表示右下—左上的对角线
void dfs(int h){  //开始深度优先搜索,定义一个int类型的h表示行
	if(h>n){  //如果实际有的行数大于棋盘的行数(从这个范围内执行判断)
		if(h>n){    //用if语句
			if(ans<=2){ //如果  //用if语句限制输出解的个数,前面给ans的初始值为0,ans<=2就会输出三个解
			for(int i=1;i<=n;++i){  //用for循环语句输出前三个解
				cout<n且符合题意的,说明找到了,满足题意的解(sum)+1;
		return;  //全部执行完了,截断。
	}		
	for(int i=1;i<=n;++i){  //循环语句,相当于从第一行(i=1)开始,到第n行
		if(a[i]==0 && b[i+h]==0 && c[i-h+n]==0){  
		//a[i]表示所在行;b[i+h]表示所在左上-右下的对角线(i加上h就可以表示);
		//c[i-h+n]表示右下-左上的对角线,正常情况下来说只用i-h就可以表示,但是有时候i会bih小,所以i-h的结果有可能是负数,所以要加n变成正数。
		//判断:如果这一行中的这个点这一列和两条对角线都为0(也就是都没有被放入棋子)(int类型的数组可以用1和0表示是否)
			d[h]=i;  //如果符合这个判断,那就把行数等于i,相当于去了下一行继续循环
			a[i]=1;  //如果符合这个判断,那就给这一行中那个点所在的那一列和两条对角线的交点赋值为1(表示已经有棋子了)
			b[i+h]=1;
			c[i-h+n]=1;
			dfs(h+1);  //查找下一行的点
			a[i]=0;    //给列和两条对角线再初始化,继续循环
			b[i+h]=0;
			c[i-h+n]=0;
		}
	}
}
int main()
{
	cin>>n;  //把棋盘的行数(也就是列数)输入进去
	dfs(1);  //从第一行开始查找
	cout<

你可能感兴趣的:(深度优先搜索问题--八皇后(洛谷1219)题解)