题目链接:hdu_2328_Corporate Identity
题意:
给你n个串,让你找这n个串的最大公共子串
题解:
串比较小,暴力枚举第一个的子串,然后KMP判断是否可行
1 #include<cstdio> 2 #include<cstring> 3 #define F(i,a,b) for(int i=a;i<=b;i++) 4 5 const int N=210; 6 int nxt[N],n,lens[4001],ans,l,r,cnt; 7 char dt[4001][N]; 8 9 int KMP(int n,char*a,int m,char*b){ 10 int i,j; 11 for(nxt[0]=j=-1,i=1;i<n;nxt[i++]=j){ 12 while(~j&&a[j+1]!=a[i])j=nxt[j]; 13 if(a[j+1]==a[i])j++; 14 } 15 for(j=-1,i=0;i<m;i++){ 16 while(~j&&a[j+1]!=b[i])j=nxt[j]; 17 if(a[j+1]==b[i])j++; 18 if(j==n-1)return 1; 19 } 20 return 0; 21 } 22 23 inline void up(int &a,int b){if(a<b)a=b;} 24 inline void update(int L,int R){ 25 if(R-L+1>ans)l=L,r=R,ans=r-l+1; 26 else if(R-L+1==ans) 27 { 28 for(int i=l,j=L;1;i++,j++){ 29 if(dt[1][i]!=dt[1][j]){ 30 if(dt[1][i]<dt[1][j])return; 31 else{ 32 l=L,r=R; 33 return; 34 } 35 } 36 if(i==r)return; 37 if(j==R)l=L,r=R; 38 } 39 } 40 } 41 42 int main(){ 43 while(~scanf("%d",&n),n) 44 { 45 F(i,1,n)scanf("%s",dt[i]),lens[i]=strlen(dt[i]); 46 char tp[201]; 47 ans=-1,l=0,r=0,cnt=0; 48 F(i,0,lens[1]-1)F(j,i+cnt,lens[1]-1) 49 { 50 51 int ed=0,fg=1; 52 F(ii,i,j)tp[ed++]=dt[1][ii]; 53 F(ii,2,n)if(KMP(j-i+1,tp,lens[ii],dt[ii])==0){fg=0;break;} 54 if(fg)update(i,j),cnt=ans<1?0:ans-1;//剪枝,每次只找大于ans的 55 } 56 if(ans==-1)puts("IDENTITY LOST"); 57 else {F(i,l,r)printf("%c",dt[1][i]);puts("");} 58 } 59 return 0; 60 }
时间: 2024-10-12 21:10:17