码迷,mamicode.com
首页 > 其他好文 > 详细

最长回文(Manacher)

时间:2015-10-25 17:51:56      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:

最长回文

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12244    Accepted Submission(s): 4501


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
 题解:manacher算法:可以求出字符串每个位置的最长字串;

if( mx > i)
    p[i]=MIN( p[2*id-i], mx-i);

就是当前面比较的最远长度mx>i的时候,Pi]有一个最小值。这个算法的核心思想就在这里,为什么P数组满足这样一个性质呢?
   (下面的部分为图片形式)


技术分享
代码:
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 #define mem(x,y) memset(x,y,sizeof(x))
 8 using namespace std;
 9 typedef long long LL;
10 const int INF=0x3f3f3f3f;
11 const int MAXN=250005;
12 int p[MAXN];
13 char str[MAXN],s[MAXN];
14 int Manacher(char *s,int len){
15     mem(p,0);
16     p[0]=p[1]=1;
17     int id=1,mx=1;
18     int ans=0;
19     for(int i=2;i<len;i++){
20         if(mx>i)p[i]=min(p[2*id-i],mx-i);
21         //找对称轴左侧这个地方和最大值地方的长度大小,找小的 
22         else p[i]=1;
23         while(s[i-p[i]]==s[i+p[i]])p[i]++;
24         if(p[i]+i>mx)mx=p[i]+i,id=i;//更新对称轴id,更新右侧匹配的最大值mx 
25         ans=max(ans,p[i]);
26     }
27     return ans-1;
28 }
29 int main(){
30     int flot=0;
31     while(~scanf("%s",str)){
32         int len=strlen(str);
33         s[0]=@;
34         for(int i=0;i<len;i++){
35             s[2*i+1]=#;
36             s[2*i+2]=str[i];
37         }
38         s[2*len+1]=#;
39     //    if(flot++)puts("");
40         printf("%d\n",Manacher(s,2*len+2));
41     }
42     return 0;
43 }

 

最长回文(Manacher)

标签:

原文地址:http://www.cnblogs.com/handsomecui/p/4908954.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!