POJ 3450 Corporate Identity(KMP:最长连续公共子序列)

来源:互联网 发布:优化农业产业结构 编辑:程序博客网 时间:2024/05/17 12:01

POJ 3450 Corporate Identity(KMP:最长连续公共子序列)

http://poj.org/problem?id=3450

题意:

        给你N个字符串,要你找出最长公共连续子串,如果存在多个,输出字典序最小的那个.

分析:

        本题基本类似于POJ3080,详见:

http://blog.csdn.net/u013480600/article/details/23026335

AC代码:110ms

<span style="font-size:18px;">#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;char s[4100][250];char P[250];char ans[250];//最终的结果字符串int m,next[250];int n;//表示有多少个主串void getFail(){    m=strlen(P);    next[0]=next[1]=0;    for(int i=1;i<m;i++)    {        int j =next[i];        while(j && P[i]!=P[j]) j=next[j];        next[i+1] = (P[i]==P[j])?j+1:0;    }}bool find(char *T){    int j=0;    getFail();    int n=strlen(T);    for(int i=0;i<n;i++)    {        while(j && T[i]!=P[j]) j=next[j];        if(T[i]==P[j]) j++;        if(j==m) return true;    }    return false;}bool solve_1(int len)//判断第0个base串的长为len的字串中是否有可行串{    int s0_len=strlen(s[0]);    for(int i=0;i+len-1<s0_len;i++)    {        strncpy(P,s[0]+i,len);        P[len]=0;//P串末尾加'\0'        bool ok=true;        for(int j=1;j<n;j++)        if(!find(s[j]))        {            ok=false;            break;        }        if(ok) return true;    }    return false;}void solve_3(int len)//找出长度为len的可行字串中字典序最小的,放在ans中{    bool first=true;    int s0_len=strlen(s[0]);    for(int i=0;i+len-1<s0_len;i++)    {        strncpy(P,s[0]+i,len);        P[len]=0;//P串末尾加'\0'        bool ok=true;        for(int j=1;j<n;j++)if(!find(s[j]))        {            ok=false;            break;        }        if(ok)        {            if(first)            {                strncpy(ans,P,len+1);                first=false;            }            else if(strcmp(ans,P)>0)//字典序小才更新                strncpy(ans,P,len+1);        }    }}bool solve(){    int L=1,R=strlen(s[0]);    if(!solve_1(1)) return false;    while(R>L)    {        int m=L+(R-L+1)/2;        if(solve_1(m))            L=m;        else            R=m-1;    }    //找到了可行字串的最长长度为L,然后需要找出字典序最小的    solve_3(L);//找到长L的字典序最小的字串存在ans中    return true;}int main(){    while(scanf("%d",&n)==1&&n)    {        for(int i=0;i<n;i++)            scanf("%s",s[i]);        if(!solve())//最终结果存在ans中            printf("IDENTITY LOST\n");        else            printf("%s\n",ans);    }    return 0;}</span>


0 0
原创粉丝点击