lightOJ 1258 Making Huge Palindromes(KMP)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1258
就是求逆串和原串的匹配长度
答案就是原串长度的2倍减去匹配长度即可
第一次我将原串接在逆串后面然后一次求失败函数得当前串的f[len1](假设当前总串长度为len1)那么答案即为了len1-f[len1],如果f[len1]>=len ,那么答案为len
但是wrong了,,不知道原因
第二次就直接匹配原串和逆串然后就AC了
我把错误代码和正确代码都贴出来,有时间再思考为什么第一个方法错吧,有哪位朋友看到也可以指导,谢啦
错误代码:
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 #define maxn 1000005 6 using namespace std; 7 char s[maxn]; 8 char s1[maxn*2]; 9 int len; 10 int len1; 11 int f[maxn*2]; 12 void callfail() 13 { 14 int i,j=0,k=-1; 15 f[0]=-1; 16 while(j<len1) 17 { 18 if(k==-1 || s1[j]==s1[k]) 19 { 20 k++;j++; 21 f[j]=k; 22 } 23 else k=f[k]; 24 } 25 } 26 int main() 27 { 28 int t; 29 while(scanf("%d",&t)!=EOF) 30 { 31 int iCase=1; 32 while(t--) 33 { 34 printf("Case %d: ",iCase++); 35 s[0]='\0'; 36 s1[0]='\0'; 37 scanf("%s",s); 38 len=strlen(s); 39 for(int i=0;i<len;i++) 40 s1[i]=s[len-1-i]; 41 s1[len]='\0'; 42 strcat(s1,s); 43 len1=strlen(s1); 44 s1[len1]='\0'; 45 callfail(); 46 if(f[len1]>=len) 47 cout<<len<<endl; 48 else 49 cout<<len1-f[len1]<<endl; 50 } 51 } 52 return 0; 53 }
正确代码:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int maxn = 1000005; 5 char a[maxn]; 6 char b[maxn]; 7 int f[maxn]; 8 9 10 void callfail() 11 { 12 int len= strlen(b); 13 f[0] =-1; 14 int j=0,k=-1; 15 while(j<len) 16 { 17 if(k==-1 || b[k]==b[j]) 18 { 19 k++;j++; 20 f[j]=k; 21 } 22 else k=f[k]; 23 } 24 } 25 int kmp() 26 { 27 int la = strlen(a); 28 int lb = strlen(b); 29 callfail(); 30 int i=0,j = 0; 31 while(i<la && j<lb) 32 { 33 if(j==-1 || a[i]==b[j]) 34 { 35 i++;j++; 36 } 37 else j=f[j]; 38 } 39 return la + lb - j; 40 } 41 42 43 int main() 44 { 45 int t; 46 scanf("%d", &t); 47 for (int i = 1; i <= t; i++) 48 { 49 scanf("%s", a); 50 int l = strlen(a); 51 for (int j = 0; j < l; j++) 52 { 53 b[l-j-1] = a[j]; 54 } 55 b[l] = '\0'; 56 printf("Case %d: %d\n", i, kmp()); 57 } 58 return 0; 59 }