POJ1226

题目大意

给定n个字符串,字符串可逆序可顺序,求它们的最长公共子串

题解

在输入的过程中记录一下最短的那个字符串,然后枚举起点,然后进行二分求出子串末位置,然后再验证是否是公共子串,记录最长的公共子串就是最终答案~~~~时间复杂度为O(N^3*logn)

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define  MAXN 105
#define INF 0x3f3f3f3f
char T[MAXN][MAXN];
int f[MAXN];
void getfail(char *p,int len)
{
    int j;
    f[0]=j=-1;
    for(int i=1;i<len;i++)
    {
        while(j>=0&&p[j+1]!=p[i]) j=f[j];
        if(p[j+1]==p[i])j++;
        f[i]=j;
    }
}
bool find(char *s,int len,int n)
{
    getfail(s,len);
    for(int i=0;i<n;i++)
    {
        int j=-1,lt=strlen(T[i]);
        bool flag1=false,flag2=false;
        for(int t=0;t<lt;t++)
        {
            while(j>=0&&s[j+1]!=T[i][t]) j=f[j];
            if(s[j+1]==T[i][t]) j++;
            if(j+1==len) 
            {
                flag1=true;
                break;
            }
        }
        char ss[MAXN];
        strcpy(ss,T[i]);
        reverse(ss,ss+lt);
        j=-1;
        for(int t=0;t<lt;t++)
        {
            while(j>=0&&s[j+1]!=ss[t]) j=f[j];
            if(s[j+1]==ss[t]) j++;
            if(j+1==len) 
            {
                flag2=true;
                break;
            }
        }
        if(!flag1&&!flag2) return false;
    }
    return true;

}
int main()
{
    int cases;
    scanf("%d",&cases);
    while(cases--)
    {
        int n,maxlen=-INF,len=INF;
        char s[MAXN];
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%s",T[i]);
            if(len>strlen(T[i]))
            {
                len=strlen(T[i]);
                strcpy(s,T[i]);
            }
        }
        for(int i=0;i<len;i++)
        {
            int l=i,r=len-1,lens=-INF;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                bool flag=find(s+i,mid-i+1,n);
                if(flag)
                {
                    l=mid+1;
                    lens=mid-i+1;
                }
                else
                    r=mid-1;
                if(lens!=-INF&&lens>maxlen) maxlen=lens;
            }
        }
        if(maxlen!=-INF)
            printf("%d
",maxlen);
        else
        {
            printf("0
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3324449.html