2018计蒜之道 第四场 B

题目链接

题意:给定m个集合,求一个序列使每个集合的所有元素都是这个序列上的一个连续子序列

思路:一开始没有理解到集合的意思错了两次,后来一看问答才反应过来,集合是一个无序的容器,要直接通过集合来找这个序列有些麻烦,然后想到可不可以把所有序列打出来根据集合判断合法性呢?一看n<=8,OK,所有序列也才4w+,求个全排列,排个序,然后再根据集合判断一下合法性就出来了

#include<algorithm>
#include<typeinfo>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<iomanip>
#include<stdio.h>
#include<math.h>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
#define pi acos(-1)
#define mod 323232323
ll gcd(ll x, ll y) { return x ? gcd(y%x, x) : y; }
ll lcm(ll x, ll y) { return x * y / gcd(x, y); }

int n, m, k, pre[1005], x, ji, vis[1005], len;
string num[50000];
void quan(int x, int ind) {
	if (ind == x)
		num[ji++] = num[0];
	else
		for (int a = ind; a < x; a++) {
			swap(num[0][ind], num[0][a]);
			quan(x, ind + 1);
			swap(num[0][ind], num[0][a]);
		}
}
void init(int x) {
	ji = 1;
	len = 1;
	for (int a = 2; a <= x; a++)
		len *= a;
	num[0] = "";
	for (int a = 0; a < x; a++)
		num[0] += a + '1';
	num[1] = num[0];
	quan(x, 0);
}

int main() {
	ios::sync_with_stdio(false);
	//cin.tie(0);
	cout << fixed << setprecision(6);

	while (~scanf("%d%d", &n, &m)) {
		init(n);
		sort(num + 1, num + len + 1);
		vector<vector<int> >ve;
		ji = 0;
		while (m--) {
			vector<int>v1;
			scanf("%d", &k);
			while (k--)
				scanf("%d", &x), v1.push_back(x);
			ve.push_back(v1);
		}
		int flag = 0;
		for (int a = 1; a <= len; a++) {
			ji = 0;
			for (int b = 0; b < ve.size(); b++) {
				vector<int>v;
				for (int c = 0; c < ve[b].size(); c++)
					v.push_back(num[a].find(ve[b][c]+'0'));
				sort(v.begin(), v.end());
				if (v[v.size() - 1] - v[0] != v.size() - 1) {
					ji = 1;
					break;
				}
			}
			if (!ji) {
				flag = 1;
				for (int b = 0; b < num[a].size(); b++) {
					if (b)
						printf(" ");
					printf("%c", num[a][b]);
				}
				printf("\n");
				break;
			}
		}
		if (!flag)
			cout << "-1" << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/icliuli/article/details/80400720