zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    QOMO Linux 4.0 正式版发布
    LinkChecker 8.1 发布,网页链接检查
    pgBadger 2.1 发布,PG 日志分析
    Aletheia 0.1.1 发布,HTTP 调试工具
    Teiid 8.2 Beta1 发布,数据虚拟化系统
    zLogFabric 2.2 发布,集中式日志存储系统
    开源电子工作套件 Arduino Start Kit 登场
    Piwik 1.9 发布,网站访问统计系统
    Ruby 1.9.3p286 发布,安全修复版本
    toBraille 1.1.2 发布,Java 盲文库
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5475427.html
Copyright © 2011-2022 走看看