HDU 2594 Simpsons’ Hidden Talents(KMP求s1前缀和s2后缀相同部分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594
题目大意:给两串字符串s1,s2,,找到最长子串满足既是s1的前缀又是s2的后缀,输出子串,及相应长度。
解题思路:这题是不是跟POJ 2752很像,没错,我们只要将s1、s2合并,不断递归直到找到长度小于等于s1、s2的公共前后缀即可。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int N=1e6+5; 8 9 int nxt[N]; 10 char s1[N],s2[N]; 11 12 void getnext(char *p,int m){ 13 int i,j; 14 i=0,j=nxt[0]=-1; 15 while(i<m){ 16 while(j!=-1&&p[i]!=p[j]) 17 j=nxt[j]; 18 nxt[++i]=++j; 19 } 20 } 21 22 int main(){ 23 while(~scanf("%s",s1)){ 24 scanf("%s",s2); 25 int m=strlen(s1),n=strlen(s2); 26 int cnt=m; 27 //合并s1,s2求nxt数组 28 for(int i=0;i<n;i++){ 29 s1[cnt++]=s2[i]; 30 } 31 s1[cnt]='\0'; 32 getnext(s1,cnt); 33 int ans=nxt[cnt]; 34 //s1、s2合并后公共前后缀长度可能大于s1或s2原来的长度,所以要回溯一下找到长度刚好小于s1、s2的公共前后缀 35 while(ans!=-1){ 36 if(ans<=m&&ans<=n) 37 break; 38 ans=nxt[ans]; 39 } 40 if(ans>0){ 41 for(int i=0;i<ans;i++){ 42 printf("%c",s1[i]); 43 } 44 printf(" %d\n",ans); 45 } 46 else 47 printf("%d\n",ans); 48 } 49 return 0; 50 }