HDU - 2328 Corporate Identity(kmp+暴力)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2328
题意:多组输入,n==0结束。给出n个字符串,求最长公共子串,长度相等则求字典序最小。
题解:(居然没t,可能数据水了吧)这个题和 HDU - 1238 基本一样,用string比较好操作。选第一个字符串然后两层循环(相当于找到所有的子串),然后和其他几个字符串比较看是否出现过,如果所有字符串中都出现了就记录下来,找出长度最大字典序最小的子串。否则输出“IDENTITY LOST”。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 string a[4100]; 5 int nt[210]; 6 7 void getNext(string p){ //比上边的nt数组往后一位 8 memset(nt,0,sizeof(nt)); 9 nt[0]=-1; 10 int i=0,j=-1; //j控制前缀,i控制后缀 11 int lp=p.length(); 12 while(i<lp){ 13 if(j==-1||p[i]==p[j]){ 14 ++i;++j; 15 nt[i]=j; 16 } 17 else j=nt[j]; 18 } 19 } 20 21 bool kmp(string t,string p){ 22 getNext(p); 23 int i=0,j=0; 24 int lt=t.length(),lp=p.length(); 25 int ans=0; 26 while(i<lt){ 27 if(j==-1||t[i]==p[j]){ 28 i++; 29 j++; 30 } 31 else j=nt[j]; 32 if(j==lp) return 1; 33 } 34 return 0; 35 } 36 37 int main() 38 { 39 ios::sync_with_stdio(false); 40 cin.tie(0); 41 cout.tie(0); 42 int n; 43 while(cin>>n&&n){ 44 for(int i=0;i<n;i++) cin>>a[i]; 45 int ans=0; 46 string str="IDENTITY LOST"; 47 for(int i=0;i<a[0].length();i++){ 48 string p; 49 for(int j=i;j<a[0].length();j++){ 50 p+=a[0][j]; 51 int flag=1; 52 for(int k=1;k<n;k++){ 53 if(!kmp(a[k],p)){ 54 flag=0; 55 break; 56 } 57 } 58 if(flag) { 59 if(ans<j-i+1) ans=j-i+1,str=p; 60 else if(ans==j-i+1) str=min(str,p); 61 } 62 else break; 63 } 64 } 65 cout<<str<<endl; 66 } 67 return 0; 68 }