HDU3068 最長回文
最長回文
Time Limit: 4000/2000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 13605Accepted Submission(s): 4947
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
分析:manacher算法的模板題,不多說了。
<span style="font-size:18px;">#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 110010
char s[MAXN],str[MAXN*2];
int p[MAXN*2];
int n;
void init()
{
int i;
str[0] = '@'; str[1] = '#';
for(i=0,n=2; s[i]; i++,n+=2)
{
str[n] = s[i];
str[n+1] = '#';
}
str[n] = 0;
}
int solve()
{
int id;
int mx=0;
int ans = 0;
for(int i=1; str[i]; i++)
{
if(mx > i)
p[i]=p[2*id-i]>(mx-i)?(mx-i):p[2*id-i];
else
p[i] = 1;
while(str[i-p[i]] == str[i+p[i]]) p[i]++;
if(p[i]+i > mx)
{
mx = p[i] + i;
id = i;
}
if(ans < p[i]) ans = p[i];
}
return ans-1;
}
int main()
{
while(scanf("%s",s)!=-1)
{
init();
printf("%d\n",solve());
}
}
</cstring></cstdio></iostream></span>