【贪心】Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals) A. String Reconstruction

在每个给出的子串的起始位置打个标记,记录的是从这里开始的最长子串。

然后输出的时候就扫,如果遇到开始位置,就从这里开始输出,如果其后被更长的覆盖,就跳转到更长的串进行输出。

如果位置没被覆盖,就输出'a'。

#include<cstdio>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
string s[100010];
int n,m,p[2000010],len[100010],nn,now;
void print(int x){
	for(int i=x,j=0;j<len[p[x]];++i,++j){
		if(!p[i] || i==x || len[p[i]]+j<=len[p[x]]){
			putchar(s[p[x]][j]);
			now=max(now,i);
		}
		else{
			print(i);
			break;
		}
	}
}
int main(){
	int x;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		cin>>s[i]>>m;
		len[i]=s[i].length();
		for(int j=1;j<=m;++j){
			scanf("%d",&x);
			if(len[i]>len[p[x]]){
				p[x]=i;
				nn=max(nn,x+len[i]-1);
			}
		}
	}
	for(int i=1;i<=nn;){
		if(p[i]){
			print(i);
			i=now+1;
		}
		else{
			putchar('a');
			++i;
		}
	}
	puts("");
	return 0;
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/7154016.html