Blue Jeans

题目大意:有M个串,每个串的长度都是60,查找这M个串的最长公共子串(连续的),长度不能小于3,如果同等长度的有多个输出字典序最小的那个。
 
分析:因为串不多,而且比较短,所致直接暴力枚举的第一个串的所有子串,比较暴力的做法,如果串的长度大一些就没法玩了。
代码如下:
====================================================================================
 
#include<stdio.h>
#include<string.h>

const int MAXN = 107;
const int oo = 1e9+7;

char s[MAXN][MAXN];
int next[MAXN];

void GetNext(char s[])
{
    int i=0, j=-1, N=strlen(s);
    next[0] = -1;

    while(i < N)
    {
        if(j==-1 || s[i]==s[j])
            next[++i] = ++j;
        else
            j = next[j];
    }
}
bool KMP(char a[], char s[])
{
    int i=0, j=0;
    int Na=strlen(a), Ns = strlen(s);

    while(i < Na)
    {
        while(j==-1 || (a[i]==s[j] && i<Na) )
            i++, j++;

        if(j == Ns)return true;

        j = next[j];
    }

    return false;
}

int main()
{
    int T;

    scanf("%d", &T);

    while(T--)
    {
        int i, j, len, M, MaxLen=60;
        char ans[MAXN] = "Z";

        scanf("%d", &M);

        for(i=0; i<M; i++)
            scanf("%s", s[i]);

        for(len=60; len>=3; len--)
        for(i=0; i<=MaxLen-len; i++)
        {///枚举第一个串的所有子串
            char b[MAXN]={0};

            strncpy(b, s[0]+i, len);
            GetNext(b);

            for(j=1; j<M; j++)
            {
                if(KMP(s[j], b) == false)
                    break;
            }

            if(j==M && strcmp(ans, b) > 0)
                strcpy(ans, b);

            if(ans[0] != 'Z' && i==MaxLen-len)
                i=100, len = 0;///跳出循环
        }

        if(ans[0] == 'Z')
            printf("no significant commonalities
");
        else
            printf("%s
", ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/liuxin13/p/4731815.html