• 【CodeForces】889 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
  • 相关阅读:
    【转】ios输入框被键盘挡住的解决办法
    【转】操作系统Unix、Windows、Mac OS、Linux的故事
    mac 下删除非空文件夹
    解决Win7 64bit + VS2013 使用opencv时出现提“应用程序无法正常启动(0xc000007b)”错误
    图的邻接表表示
    图的邻接矩阵表示
    并查集
    05-树9 Huffman Codes及基本操作
    05-树7 堆中的路径
    堆的操作集
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8576383.html
Copyright © 2020-2023  润新知