题意:求一个字符串的最长回文子串
题解:是一个Manacher模板题,为了统一奇偶,先预处理在字符间添加间隔,使字符串长度变为偶数,例如"abc"添加分隔符后变成"$#a#b#c#",剩下的就很简单了,这个题也可以用哈希做。就时间复杂度来看Manacher明显比哈希快。
Manacher代码
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<string> 5 using namespace std; 6 7 int p[2000020];//p数组需要开至少字符串两倍的空间 8 char s[1010100]; 9 10 int Manacher(char str[]) 11 { 12 memset(p,0,sizeof(p)); 13 string s="$#"; 14 int len=strlen(str); 15 for(int i=0;i<len;i++){ 16 s+=str[i]; 17 s+='#'; 18 } 19 int mx=0,id=0,reslen=0,rescenter=0; 20 len=s.length(); 21 for(int i=1;i<=len;i++) 22 { 23 p[i]=mx>i?min(p[2*id-i],mx-i):1;// 24 while(s[i+p[i]]==s[i-p[i]])p[i]++; 25 if(mx<i+p[i]) 26 { 27 mx=i+p[i]; 28 id=i; 29 } 30 if(reslen<p[i]) 31 { 32 reslen=p[i]; 33 rescenter=i; 34 } 35 } 36 return reslen-1; 37 } 38 39 40 int main() 41 { 42 int t=1; 43 while(~scanf("%s",s)){ 44 if(strcmp(s,"END")==0) break; 45 printf("Case %d: %d\n",t++,Manacher(s)); 46 } 47 return 0; 48 }
哈希代码
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<math.h> 5 #include<iostream> 6 using namespace std; 7 8 const int maxn = 2e6+20; 9 const int base = 131; //不易冲突 10 typedef unsigned long long ULL; 11 ULL f[maxn], f2[maxn], t[maxn]; 12 13 char s[maxn]; 14 ULL solve(ULL h[],int l, int r) 15 { 16 return h[r] - h[l-1] * t[r-l+1]; 17 } 18 19 int main() 20 { 21 int T = 1; 22 while(scanf("%s", s+1) != EOF) { 23 int len = strlen(s+1); 24 if(!strcmp(s+1, "END")) 25 break; 26 for(int i = 2*len; i > 0; i-=2) { 27 s[i] = s[i/2]; 28 s[i-1] = 'z'+1; 29 } 30 len *= 2; 31 f[0] = f2[0] = 0; 32 t[0] = 1; 33 for(int i = 1, j = len; i <= len; i++, j--) { 34 f[i] = f[i-1]*base + (s[i] - 'a' + 1); 35 f2[i] = f2[i-1]*base + (s[j] - 'a' + 1); 36 t[i] = t[i-1] * base; 37 } 38 int l, r; 39 int ans = 0; 40 int mid; 41 for(int i = 1; i <= len; i++) { 42 l = 0, r = min(i-1, len-i); 43 while(l < r) { 44 mid = (l+r+1)>>1; 45 if(solve(f,i-mid,i-1) != solve(f2,len-(i+mid)+1,len-(i+1)+1)) 46 r = mid-1; 47 else l = mid; 48 } 49 if(s[i-l] <= 'z') 50 ans = max(ans, l+1); 51 else 52 ans = max(ans, l); 53 } 54 printf("Case %d: %d\n", T++, ans); 55 } 56 return 0; 57 }