POJ 1226 && HDU 1238 Substrings(kmp)

Desciption
给出n个字符串,求出一个最长的串,使得这个串或者这个串的回文在所有n个字符串中都出现
Input
第一行为用例组数t,每组用例第一行为串数n,之后n行每行一个字符串
Output
对于每组用例,输出满足条件的最长串长
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
Solution
枚举第一个串的所有子串及其反串,在其他串中用kmp大法找匹配即可
Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[111][111],temp1[111],temp2[111];
int nex[111];
void copy(char *a,char *b,int s,int t)//将b串[s,t]区间的值赋给a串 
{
    int k=0;
    for(int i=s;i<=t;i++)
        a[k++]=b[i];
    a[k]='\0';
}
void get_next(char *a)//得到next数组 
{
    int l=strlen(a);
    for(int i=0,j=-1;i<=l;i++,j++)
        {
            nex[i]=j;
            while(~j&&a[i]!=a[j])
                j=nex[j];
        }
    return ;
}
bool kmp(char *a,char *b)
{
    get_next(b);
    int la=strlen(a),lb=strlen(b);
    for(int i=0,j=0;i<=la;i++,j++)
        {           
            if(j==lb)
                return true;
            while(~j&&a[i]!=b[j])
                j=nex[j];
        }
    return false;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        int len=strlen(s[0]),ans=0;
        for(int i=0;i<len;i++)//枚举第一个串的所有子串 
            for(int j=i;j<len;j++)
            {
                copy(temp1,s[0],i,j);
                int len1=strlen(temp1),k;
                for(k=0;k<len1;k++)
                    temp2[k]=temp1[len1-k-1];
                temp2[k]='\0';
                for(k=1;k<n;k++)
                    if(!kmp(s[k],temp1)&&!kmp(s[k],temp2))//如果该子串正反都不满足条件则退出循环 
                        break;
                if(k==n)//该子串满足条件,更新最大值 
                    ans=max(ans,j-i+1);
            }
        cout<<ans<<endl;
    }
    return 0;
}

你可能感兴趣的:(POJ 1226 && HDU 1238 Substrings(kmp))