PKU 1226 Substrings(字符串匹配+暴搜KMP模板)

原题大意:原题链接

给出n个字符串,找出一个最长的串s,使s或者s的反转字符串(只要其中一个符合就行)同时满足是这n个串的子串。

对于样例,第一组ABCD   BCDFF  BRCD最长的串就是CD;第二组rose  orchid最长的子串就是ro

#include<cstdio>   
#include<cstring>  
#include<iostream>   
using namespace std;    
char str[101][101];  
int next[101],rnext[101];  

/*
void get_next(char *s)
{
    next[1]=0;
    int i=1,j=0;
    int slen=strlen(s);
    while(i<slen){
        if(j==0||s[i-1]==s[j-1]){
            i++,j++;
            next[i]=j;
        }
        else j=next[j];
    }
}
在t字符串在s字符串中匹配 
bool KMP(char *s,char *t)
{
    int i=0,j=1;
    int slen=strlen(s),tlen=strlen(s);
    while(i<=slen&&j<=tlen){
        if(j==0||s[i-1]==t[j-1])
            i++,j++;
        else j=next[j];
    }
    if(j>tlen)
        return true;    
    return false;
} 
*/ 
void get_next(int l,int r,bool flag)  
{  
    if(flag){  
        next[l]=l-1;  
        int i=l,j=l-1;  
        while(i<r){  
            if(j==l-1||str[0][i]==str[0][j]){  
                i++,j++;  
                next[i]=j;  
            }  
            else  j=next[j];       
        }  
    }  
    else{  
        rnext[r]=r+1;  
        int i=r,j=r+1;  
        while(i>l){  
            if(j==r+1||str[0][i]==str[0][j]){  
                i--,j--;
                rnext[i]=j;  
            }  
            else  j=rnext[j];
        }  
    }  
}
//将第一个字符串的l~r位置在第k个字符串中进行匹配    
bool KMP(int id,int l,int r,bool flag)  
{    
    int len=strlen(str[id]);  
    if(flag){
        int i=0,j=l;
        while(i<len&&j<=r){
            if(j==l-1||str[id][i]==str[0][j])  
                i++,j++;  
            else  j=next[j];
        }   
        if(j>r) return true;    
    }  
    else{  
        int i=0,j=r;
        while(i<len&&j>=l){  
            if(j==r+1||str[id][i]==str[0][j])  
                i++,j--;  
            else  j=rnext[j];
        }  
        if(j<l) return true;  
    }  
    return false;  
}  
  
int main()  
{  
    int T,n;
    scanf("%d",&T);  
    while(T--){  
        scanf("%d",&n);  
        for(int i=0;i<n;i++)  
            scanf("%s",str[i]);  
        int len=strlen(str[0]),ans=0;  
        for(int i=0;i<len;i++){    
            for(int j=i;j<len;j++){  
                int len=j-i+1;  
                get_next(i,j,true);  
                get_next(i,j,false);  
                int cnt=1;  
                for(int k=1;k<n;k++){ 
                    if(KMP(k,i,j,true)||KMP(k,i,j,false))  
                        cnt++;  
                    else  break;  
                }  
                if(cnt==n&&ans<len)  ans=len;  
            }  
        }  
        printf("%d\n",ans);  
    }  
    return 0;  
}  

 

posted @ 2017-02-27 20:56  despair_ghost  阅读(255)  评论(0编辑  收藏  举报