poj 1226:Substrings

給一些字符串,求它們的最長公共子串。


這道題數據量很小,可以直接暴力枚舉。枚舉第一個字符串的每個子串與其逆序串,kmp判斷是否在其他所有的字符串當中,之後再取其中最長的長度,輸出即可。


代碼:

//Memory: 232K		Time: 63MS
//Language: C++		Result: Accepted


#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

char s[105][105];
int n;
char t[105];
char _t[105];
int next[2][105];

void GetNext(char* t,int x){
    int i=-1,j=0,len=strlen(t);
    next[x][0]=-1;
    while(j<len){
        if(i==-1 || t[i]==t[j]){
            if(t[++i]==t[++j]) next[x][j]=next[x][i];
            else next[x][j]=i;
        }
        else i=next[x][i];
    }
}

bool kmp(){
    int i=0,j=0,len=strlen(t),lens;
    GetNext(t,0);
    GetNext(_t,1);
    for(int k=1;k<n;k++){
        lens=strlen(s[k]);
        if(len>lens) return false;
        i=0;j=0;
        while(i<len && j<lens){
            if(i==-1 || t[i]==s[k][j]) {i++;j++;}
            else i=next[0][i];
        }
        if(i>=len) continue;
        else {
            i=0;j=0;
            while(i<len && j<lens){
                if(i==-1 || _t[i]==s[k][j]) {i++;j++;}
                else i=next[1][i];
            }
            if(i<len) return false;
        }
    }
    return true;
}

int main(){
    //freopen("in.txt","r",stdin);
    int T; cin>>T;
    while(T--){
        int ans=0;
        cin>>n;
        for(int i=0;i<n;i++){
            scanf("%s",s[i]);
        }
        for(int i=0;i<strlen(s[0]);i++){
            memset(t,0,sizeof(t));
            memset(_t,0,sizeof(_t));
            for(int j=i;j<strlen(s[0]);j++){
                for(int k=0;i+k<=j;k++){
                    t[k]=s[0][i+k];
                    _t[k]=s[0][j-k];
                }
                if(kmp()) ans=(ans>(j-i+1))?ans:(j-i+1);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章