1. 程式人生 > >POJ 3450 Corporate Identity(kmp求多個字串的最長公共子串)

POJ 3450 Corporate Identity(kmp求多個字串的最長公共子串)

http://poj.org/problem?id=3450
#include <stdio.h>
#include <string.h>

const int max_N=4001;
const int max_l=201;

int n;
char res[max_l],dict[max_N][max_l];
int nexts[max_N];

int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}

void get_nexts(char *s,int len)
{
    memset
(nexts,0,sizeof(nexts)); for(int i=1,j=0;i<len;) { if(s[i]==s[j])nexts[i++]=++j; else if(j>0) j=nexts[j-1]; else i++; } } int get_longestpre(char *s,int len) { get_nexts(s,len); for(int i=1;i<n;i++) { char *p=dict[i]; int j=0,tmp=0
; for(;*p&&j<len;) { if(*p==s[j]) { p++,j++; tmp=max(tmp,j); } else if(j>0) j=nexts[j-1]; else p++; } len=tmp; } return len; } int main() { while(scanf
("%d",&n)&&n) { getchar(); for(int i=0;i<n;i++) { gets(dict[i]); } int len=strlen(dict[0]),ans=0,pos=0; for(int i=0;i<len;i++) { int tmp=get_longestpre(dict[0]+i,len-i); if(tmp>=ans) { if(tmp>ans) { ans=tmp; pos=i; } else { bool smaller =true; for(int t=0;t<ans;t++) { if(dict[0][pos+t]>dict[0][i+t]) break; else if(dict[0][pos+t]<dict[0][i+t]) { smaller=0; break; } } if(smaller) pos=i; } } } if(ans) { for(int i=0;i<ans;i++) putchar(dict[0][pos+i]); printf("\n"); } else puts("IDENTITY LOST"); } return 0; }