ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P1219 八皇后

2019-09-09 21:00:24  阅读:257  来源: 互联网

标签:pre 洛谷 int 数值 棋子 对角线 ind 皇后 P1219


题目描述

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

上面的布局可以用序列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大小的。

输出格式

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

输入输出样例
输入 #1

6

输出 #1

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4


思路

1->n行,每行存入不同的列数值即可满足各行各列有且只有一个棋子,且此时行数值和列数值就可代表各棋子的坐标,设某一棋子的行数为ind1,列数值为val1,另一棋子的行数为ind2,列数值为val2,则只要当abs(ind1 - ind2) != abs(val1 - val2)即可说明各对角线及其平行线上有且只有一个棋子。

dfs进入各行,为每一行找一个符合要求(judge函数)的列数值即可。

#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 15;
int n, ans[maxn], cnt;   // ans保存每一行的列数,cnt为解的个数
bool used[maxn] = {false};

// 判断在第ind行存入列数值val是否可行
bool judge(int ind, int val) {
	if (used[val]) return false;   // 前面的某一行已经存过这个列数值了
	// 遍历之前已经存好了列数值的各行,判断是否满足各对角线及其平行线上只有一个棋子
	for (int pre = 1; pre < ind; ++pre) {
		// 行数值的绝对值之差不等于列数值的绝对值之差即可说明
		// 各对角线及其平行线上有且只有一个棋子
		if ( abs(pre - ind) == abs(ans[pre] - val) ) return false;
	}
	return true;
}

// 当前行数为ind
void dfs(int ind) {
	if (ind == n + 1) {
		cnt ++;
		if (cnt <= 3) {
			for (int i = 1; i <= n; ++i) {
				printf("%d", ans[i]);
				i != n ? printf(" ") : printf("\n");
			}
		}
		return;
	}
	// 遍历列数值val,若合适则存入该ind行中
	for (int val = 1; val <= n; ++val) {
		if (judge(ind, val)) {
			used[val] = true;
			//if (cnt < 3) ans[ind] = val;
			ans[ind] = val;
			dfs(ind + 1);
			used[val] = false;
		}
	}
}

int main() {
	scanf("%d", &n);
	dfs(1);
	printf("%d\n", cnt);
	return 0;
}

标签:pre,洛谷,int,数值,棋子,对角线,ind,皇后,P1219
来源: https://blog.csdn.net/xihao1229/article/details/100672912

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有