poj 3450

题意:给你n个的串,求出它们的最长公共子串,如果不存在这个子串,则输出“IDENTITY LOST”,如果存在多个最长公共子串,则输出字典序最小的那一个。

思路:枚举+KMP。与poj3080类似,详情见poj3080

#include<iostream>
#include<cstring>
using namespace std;
const int nMax = 4002;
const int mMax = 202;

char text[nMax][mMax], pat[mMax];
int n, ma, lent[nMax], lenp, next[mMax];

void get_next()
{
    int j=1, k=0;
    next[0] = -1;
	next[1]=0;
    while(j< lenp)
	{
        if(pat[j] == pat[k])
		{
			next[j+1]=k+1;
			j++;
			k++;
        }
		else if (k==0)
		{
			next[j+1]=0;
			j++;
		}
		else
			k=next[k];
    }
}

void KMP()
{
    int k, m, i, j;
    get_next();
    ma = 200;
    for(k = 1; k < n; k ++)
	{
        i = 0; j = 0; m = 0;
        while(i < lent[k] && j < lenp)
		{
            if(j == -1 || text[k][i] == pat[j])
			{
                i ++; 
				j ++;
            }
            else j = next[j];
            if(j > m)
				m = j;
        }
        if(m < ma) ma = m;
    }
}

int main()
{
    int i;
    char result[mMax], tmp[mMax];
    while(scanf("%d", &n) && n)
	{
        for(i = 0; i < n; i ++)
		{
            scanf("%s", text[i]);
            lent[i] = strlen(text[i]);
        }
        int ans = 0;
        for(i = 0; i < lent[0]; i ++)
		{
            strcpy(pat, text[0] + i);
            lenp = lent[0] - i;
            KMP();
            if(ans < ma)
			{
                ans = ma;
                strncpy(result, text[0] + i, ans);
                result[ans] = '\0';
            }
            else if(ans == ma)
			{
                strncpy(tmp, text[0] + i, ans);
                tmp[ans] = '\0';
                if(strcmp(tmp, result) < 0)
                    strcpy(result, tmp);
            }
        }
        if(ans == 0) 
			printf("IDENTITY LOST\n");
        else 
			printf("%s\n", result);
    }
    return 0;
}

 

 

你可能感兴趣的:(poj)