CodeForces889 B. Restoration of string

Posted ONION_CYC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces889 B. Restoration of string相关的知识,希望对你有一定的参考价值。

【题目】B. Restoration of string

【题意】当一个字符串在字符串S中的出现次数不小于任意子串的出现次数时,定义这个字符串是高频字符串。给定n个字符串,求构造出最短的字符串S满足着n个字符串都是高频字符串,若不存在输出NO,若存在多个输出字典序最小的一个。n<=10^5,Σ|si|<=10^5。

【算法】模拟(图论?字符串?)

【题解】首先出现频率都是1次,多次没有意义,所以每个字母至多出现一次。

那么对于出现在n个字符串中的子串ab,要求在S中ab也必须相邻。

所以对n个字符串中出现的相邻字符连有向边,如果图是若干条独立的单链,那么按字典序输出这些链就是答案,否则无解。

无解包括:不是单链(有分叉)和有环。

技术分享图片
#include<cstdio>
#include<cstring>
const int maxn=100010;
char s[maxn];
bool vis[maxn];
int n,nex[maxn],pre[maxn],sum=0;
int main(){
    scanf("%d",&n);
    memset(nex,-1,sizeof(nex));memset(pre,-1,sizeof(pre));
    for(int i=1;i<=n;i++){
        scanf("%s",s);int len=strlen(s);
        for(int j=1;j<len;j++){
            int c=s[j-1]-a,d=s[j]-a;
            if((~nex[c]&&nex[c]!=d)||(~pre[d]&&pre[d]!=c))return puts("NO"),0;
            nex[c]=d;pre[d]=c;vis[d]=1;
        }
        vis[s[0]-a]=1;
    }
    for(int i=0;i<26;sum+=vis[i++])if(vis[i]&&pre[i]==-1)for(int j=i;~j;j=nex[j])sum--;
    if(sum)return puts("NO"),0;
    for(int i=0;i<26;sum+=vis[i++])if(vis[i]&&pre[i]==-1)for(int j=i;~j;j=nex[j])printf("%c",j+a);
    return 0;
}        
View Code

 

以上是关于CodeForces889 B. Restoration of string的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 889F Letters Removing(二分 + 线段树 || 树状数组)

[codeforces 260]B. Ancient Prophesy

codeforces 655B B. Mischievous Mess Makers(贪心)

codeforces 653B B. Bear and Compressing(dfs)

Codeforces Round #352 (Div. 2) B. Different is Good

CodeForces B. Obtaining the String