题意
求给定字符串的最长回文子串的长度.
思路
马拉车算法或者字符串hash
代码
马拉车算法
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2e6+10;
char Ma[maxn];
int Mp[maxn];
void Manacher(char s[],int len){
int l=0;
Ma[l++]='$';Ma[l++]='#';
for(int i=1;i<=len;i++) Ma[l++]=s[i],Ma[l++]='#';
Ma[l]=0;
int mx=0,id=0;
for(int i=0;i<l;i++){
Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;
while(Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++;
if(i+Mp[i]>mx) mx=i+Mp[i],id=i;
}
}
char s[maxn*2];
int main(){
int id=0;
while(~scanf("%s",s+1)){
if(s[1]=='E'&&s[2]=='N'&&s[3]=='D') break;
int len=strlen(s+1);
Manacher(s,len);
int ans=0;
for(int i=0;i<2*len+2;i++)
ans=ans>Mp[i]-1?ans:Mp[i]-1;
printf("Case %d: %d\n",++id,ans);
}
// system("pause");
return 0;
}
字符串hash
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=2e6+10;
int P=131;
unsigned long long h1[maxn],h2[maxn],p[maxn];
char s[maxn],tmp[maxn];
int main(){
int id=0;
while(~scanf("%s",s+1)){
if(s[1]=='E'&&s[2]=='N'&&s[3]=='D') break;
tmp[0]='$',tmp[1]='#';
int n=strlen(s+1);
int len=1;
for(int i=1;i<=n;i++){
tmp[++len]=s[i];
tmp[++len]='#';
}
tmp[len+1]='\0';
p[0]=1;
for(int i=1;i<=len;i++){
h1[i]=h1[i-1]*P+tmp[i];
p[i]=p[i-1]*P;
}
for(int i=len;i>=1;i--) h2[i]=h2[i+1]*P+tmp[i];
int ans=1,l;
for(int i=1;i<=len;i++){
l=ans;
if(i+l>len||i-l<0) break;
if(h1[i+l]-h1[i]*p[l]!=h2[i-l]-h2[i]*p[l]) continue;
while(tmp[i+l+1]==tmp[i-l-1]&&i+l-1<=len&&i-l+1>=0) l++;
ans=ans>l?ans:l;
}
printf("Case %d: %d\n",++id,ans);
}
// system("pause");
}