2019牛客暑期多校训练营(第五场)H subsequence 2【拓扑排序】

题意:

给你一个长度为n的隐藏字符串,由m个小写字符组成,接下来每一次会进行m*(m-1)/2次操作,给你两个不同的小写字符,以及把除这两个字符以外的字符删掉的字符串,以及他的长度,请问这个字符串是否存在,如果存在写出其中一种。

题目链接:

https://ac.nowcoder.com/acm/contest/885/H

题解:

拓扑排序基础练习题...对不起 我不会基础

我们可以给每个字符标记一个特定唯一的id,标记方式为 从左往右第几个某个字母

比如第14个b记录为   10014

bcbcbc

10001 20001 10002 20002 10003 20003

然后我们把子字符串相邻的字符建边,如果该图可以跑出拓扑排序就一定答案,且答案是拓扑排序

AC_code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 5;
vector<int> vec[maxn*30];
int indeg[maxn*30],num[27],sum;
int main() {
	int n, m;
	cin >> n >> m;
	int cnt = m * (m - 1) / 2;
	while (cnt--) {
		string op,t;
		int len;
		cin >> op>>len;
		if(!len) {
			getchar();
			continue;
		}
		cin>>t;
		int a=0,b=0,cur=0,id=0;
		for (int i = 0; i < len; ++i) {  
			if(t[i]==op[0]) {
				a++;
				id=(t[i]-'a')*10000+a;
			} else {
				b++;
				id=(t[i]-'a')*10000+b;
			}
			if(cur) {
				indeg[id]++;
				vec[cur].push_back(id);
			}
			cur=id; 
		}
		num[op[0]-'a']=a;
		num[op[1]-'a']=b;
	} 
	queue<int> q;
	for (int i = 0; i < 26; i++) {
		if (num[i]&&indeg[i*10000+1] == 0) {
			q.push(i*10000+1);
		}
	}
	string ans;
	while (!q.empty()) {
		int top = q.front();
		q.pop();
		ans += (char)((top-1)/10000 + 'a');
		for (auto v : vec[top]) {
			indeg[v]--;
			if (indeg[v] == 0) {
				q.push(v);
			}
		}
	}
	if (ans.size() != n) {
		cout << -1 << endl;
	} else {
		cout << ans << endl;
	}
}

 

全部评论

相关推荐

点赞 评论 收藏
分享
喜欢吃蛋糕仰泳鲈鱼是我的神:字节可以找个hr 给你挂了,再放池子捞
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务