POJ3080 - Blue Jeans(KMP+二分)
题目大意
求N个字符串的最长公共字串
题解
和POJ1226做法一样。。。注意是字典序最小的。。。WA了一次
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAXN 65 char p[MAXN],T[MAXN][MAXN]; int f[MAXN]; void getfail(char *p,int len) { int j; f[0]=j=-1; for(int i=1;i<len;i++) { while(j>=0&&p[j+1]!=p[i]) j=f[j]; if(p[j+1]==p[i]) j++; f[i]=j; } } bool find(char *s,int len,int n) { getfail(s,len); for(int t=0;t<n;t++) { int j=-1,lens=strlen(T[t]); bool flag=false; for(int i=0;i<lens;i++) { while(j>=0&&s[j+1]!=T[t][i]) j=f[j]; if(s[j+1]==T[t][i]) j++; if(j+1==len) { flag=true; break; } } if(!flag) return false; } return true; } int main() { int cases; scanf("%d",&cases); while(cases--) { int n; scanf("%d",&n); char s[MAXN],temp[MAXN]; temp[0]='\0'; for(int i=0;i<n;i++) scanf("%s",T[i]); strcpy(s,T[0]); int len=strlen(s); for(int i=0;i<len;i++) { char ss[MAXN]; ss[0]='\0'; int l=i,r=len-1; while(l<=r) { int mid=(l+r)>>1; bool flag=find(s+i,mid-i+1,n); if(flag) { l=mid+1; strncpy(ss,s+i,mid-i+1); ss[mid-i+1]='\0'; } else r=mid-1; } if(strlen(ss)>strlen(temp)||(strlen(ss)==strlen(temp)&&strcmp(ss,temp)==-1)) strcpy(temp,ss); } if(strlen(temp)>=3) printf("%s\n",temp); else printf("no significant commonalities\n"); } return 0; }