• bzoj 2946


    Description

     
           给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
    任务:
    l        读入单词
    l        计算最长公共子串的长度
    l        输出结果
     

    Input

     
    文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
     

    Output

    仅一行,一个整数,最长公共子串的长度。
     

    Sample Input

    3
    abcb
    bca
    acbc

    Sample Output

     
    同poj3450,这里多一种SAM做法
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MN 200002
    using namespace std;
    
    struct po{
        int t[26],f,l;
        po(){
            f=-1;l=0;
        }
    }t[MN];
    int num=0,n,la=0,T,MMH,p,m;
    char s[100000];
    int mmh[MN],mmh_[MN];
    inline void add(int x){
        int p=++num,o,ne;
        t[p].l=t[la].l+1;
        while (la!=-1&&!t[la].t[x]) t[la].t[x]=p,la=t[la].f;
        if (la==-1) t[p].f=0;else{
            o=t[la].t[x];
            if (t[o].l==t[la].l+1) t[p].f=o;else{
                ne=++num;
                t[ne]=t[o];
                t[ne].l=t[la].l+1;
                t[o].f=t[p].f=ne;
                while (la!=-1&&t[la].t[x]==o) t[la].t[x]=ne,la=t[la].f;
            }
        }
        la=p;
    }
    inline int max(int a,int b){return a>b?a:b;}
    inline int min(int a,int b){return a<b?a:b;}
    int main(){
        int i,j,k;
        scanf("%d",&T);
        scanf("%s",s);n=strlen(s);T--;
        for (i=0;i<n;i++) add(s[i]-'a');
        memset(mmh,60,sizeof(mmh));
        while (T--){
            memset(mmh_,0,sizeof(mmh_));
            scanf("%s",s);
            n=strlen(s);
            p=0;m=0;
            for (i=0;i<n;i++)
            if (t[p].t[s[i]-'a']){
                p=t[p].t[s[i]-'a'];mmh_[p]=max(mmh_[p],++m);
                for (k=p;t[k].f!=-1;k=t[k].f) mmh_[t[k].f]=max(mmh_[t[k].f],min(mmh_[k],t[t[k].f].l));
            }else{
                while (p!=-1&&!t[p].t[s[i]-'a']) p=t[p].f;
                if (p!=-1) m=mmh_[p]+1,p=t[p].t[s[i]-'a'],mmh_[p]=max(mmh_[p],m);else p=0,m=0;
                for (k=p;t[k].f!=-1;k=t[k].f) mmh_[t[k].f]=max(mmh_[t[k].f],min(mmh_[k],t[t[k].f].l));
            }
            for (i=1;i<=num;i++) mmh[i]=min(mmh[i],mmh_[i]);
        }
        MMH=0;
        for (i=1;i<=num;i++) MMH=max(MMH,mmh[i]);
        printf("%d
    ",MMH);
    }
    24340 kb 356 ms C++/Edit 1804 B
  • 相关阅读:
    http url转义字符,特殊字符
    No bean named &#39;cxf&#39; is defined
    c语言中结构体指针
    Android fragment (二)
    文件I/O之C标准库函数和系统库函数差别
    计算机组成原理——主存与cache的映射关系
    openstack 用nova API 指定 compute node 创建 instance
    SQL存在一个表而不在还有一个表中的数据
    hdu 2602
    小金登陆游戏
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5475427.html
Copyright © 2020-2023  润新知