Problem Description
给出一个只由小写英文字符
a,b,c...y,z
组成的字符串 S ,求 S 中最长回文串的长度.
回文就是正反读都是一样的字符串,如
aba,abba
等
Input
输入有多组 case ,不超过 120 组,每组输入为一行小写英文字符
a,b,c...y,z
组成的字符串 S
两组 case 之间由空行隔开 (该空行不用处理)
字符串长度
len<=110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
abab
Sample Output
4
3
Source
2009 Multi-University Training Contest 16 - Host by NIT
Solution
这题是求最长回文子串的裸题!
由于数据规模和题目限制,这题只能用时间空间复杂度都是 O(N) 的
——
Manacher算法
Manacher 算法 具体请参见我的博客:http://blog.csdn.net/liyizhixl/article/details/54347434
这样直接套用,就可以卡常过这题啦!
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110002*2;
char s[N*2];
int p[N*2];
int ans,id;
int main()
{
while(scanf("%s",s)!=EOF)
{
int len=strlen(s);
for(int i=len;i>=0;i--)
{
int k=i*2+1;
s[k+1]=s[i],s[k]='#';
}
len*=2;
s[ans=id=0]='*';
for(int i=2;i<=len;i++)
{
if(p[id]+id>i) p[i]=min(p[id*2-i],p[id]+id-i); else p[i]=1;
while(s[i-p[i]]==s[i+p[i]]) p[i]++;
if(p[i]+i>p[id]+id) id=i;
if(p[i]>ans) ans=p[i];
}
printf("%d\n",ans-1);
}
return 0;
}