题目描述 给出几个由小写字母构成的单词,求它们最长的公共子串的长度。 任务: l 读入单词 l 计算最长公共子串的长度 l 输出结果 输入格式 文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。 输出格式 仅一行,一个整数,最长公共子串的长度。 样例一 input 3 abcb bca acbc output 2 限制与约定 时间限制:1s1s 空间限制:256MB
这道题看起来十分复杂,其实就是暴力二分长度
然后在第一个串中框一个这么长的串去其他的里面去验证
代码在此
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MA 2011 5 #define seed 1313131 6 using namespace std; 7 typedef unsigned long long ull; 8 int n,l=1,r=0x7f7f7f7f,ans; 9 char in[10][MA]; 10 int len[10]; 11 ull vv[10][MA],se[MA]; 12 inline bool check(int lenn) 13 { 14 for(int i=1;i+lenn-1<=len[1];i++) 15 { 16 int l=i,r=i+lenn-1; 17 int yeah=0; 18 ull val=vv[1][r]-vv[1][l-1]*se[lenn]; 19 for(int j=2;j<=n;j++) 20 { 21 int kk=0; 22 for(int k=1;k+lenn-1<=len[j];k++) 23 { 24 int ll=k,rr=k+lenn-1; 25 if(val==vv[j][rr]-vv[j][ll-1]*se[lenn]){kk=1;break;} 26 } 27 if(kk)yeah++; 28 } 29 if(yeah==n-1)return 1; 30 } 31 return 0; 32 } 33 int main() 34 { 35 scanf("%d",&n); 36 se[0]=1; 37 for(int i=1;i<MA;i++)se[i]=se[i-1]*seed; 38 for(int i=1;i<=n;i++) 39 { 40 scanf("%s",in[i]+1); 41 int ll=strlen(in[i]+1); 42 len[i]=ll,r=min(r,ll); 43 for(int j=1;j<=len[i];j++) 44 vv[i][j]=vv[i][j-1]*seed+in[i][j]; 45 } 46 while(l<=r) 47 { 48 int mid=(l+r)/2; 49 if(check(mid))l=mid+1,ans=mid; 50 else r=mid-1; 51 } 52 printf("%d ",ans); 53 } 54 /* 55 4 56 alamakotaipsa 57 olamakotaikure 58 kotaipsa 59 ewamaswinkekotaipsa 60 */