POJ3080-Blue Jeans(KMP,水)

大致题意:

就是求k个长度为60的字符串的最长连续公共子串,2<=k<=10

规定:

1、  最长公共串长度小于3不输出

2、  若出现等长的最长的子串,则输出字典序最小的串


思路:和POJ-3450-Corporate Identity一样二分+枚举,但是直接暴力也0ms

//192 KB	0 ms	题目太水,我就把POJ3450的代码改了几句话
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char str[4010][210];
char minstr[210],tmp[210];
int next[210];
int lens[4010];
int n;
void getnext()
{
    next[0]=-1;
    int i=0,j=-1;
    while(tmp[i]!=0){
        while(j>-1&&tmp[i]!=tmp[j])
            j=next[j];
        j++;
        i++;
        next[i]=j;
    }
}
bool KMP()
{
    getnext();
    int lenm=strlen(tmp);
    for(int k=1;k<=n;k++){
        int i=0,j=0;
        while(i<lens[k]&&j<lenm){
            if(j==-1||str[k][i]==tmp[j]){
                i++;
                j++;
            }
            else j=next[j];
        }
        if(j!=lenm) return false;
    }
    return true;
}
bool ok(int x)
{
    int len=strlen(minstr);
    for(int i=0;i<=len-x;i++){
        strncpy(tmp,minstr+i,x);
        tmp[x]='\0';
        if(KMP()) return true;
    }
    return false;
}
int main()
{
    int _;
    scanf("%d",&_);
    while(_--){
        scanf("%d",&n);
        int minn=(1<<30);
        for(int i=1;i<=n;i++) {
            scanf("%s",str[i]);
            lens[i]=strlen(str[i]);
            if(minn>lens[i]){
                minn=lens[i];
                strcpy(minstr,str[i]);
            }
        }
        int lb=0,ub=minn+1;
        while(ub-lb>1){
            int mid=(lb+ub)/2;
            if(ok(mid)) lb=mid;
            else ub=mid;
        }

        char ans[210],first=1;
        for(int i=0;lb>=3&&i<=minn-lb;i++){
            strncpy(tmp,minstr+i,lb);
            tmp[lb]='\0';
            if(KMP()){
                if(first) {
                    first=0;
                    strcpy(ans,tmp);
                }
                else {
                    if(strcmp(ans,tmp)>0)
                        strcpy(ans,tmp);
                }
            }
        }
        if(lb>=3) printf("%s\n",ans);
        else printf("no significant commonalities\n");
    }
    return 0;
}



你可能感兴趣的:(POJ3080-Blue Jeans(KMP,水))