HDU 3068 最长回文 (manacher算法)
来源:互联网 发布:销售单软件 编辑:程序博客网 时间:2024/05/16 05:47
最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11226 Accepted Submission(s): 4030
Total Submission(s): 11226 Accepted Submission(s): 4030
Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaaabab
Sample Output
43
这是一道标准的回文串模板题, 因为题目是120组*110000的规模,暴力就是在花式作死。用时间复杂度为O(n)的manacher算法就很适合这一题。
manacher算法的大致过程如下:
先在两个相邻字符之间插入一个在串中未出现过的分隔符,这样串就变成了奇数串,也就不用把奇数串跟偶数串分开考虑了。其后就是判断回文串,并且利用之前判断过的回文串来减少重复匹配。因为根据回文串的特性,如果当前判断的字符在一个之前已经判定过的回文串内那么以该字符为对称中心的回文串必定存在一个最小值。
记点id为大回文串的对称点,mx为串id的对称半径覆盖的最大点。d[i] = min(mx-i,d[2*id-i])。2*id-i求出的点是字符在大回文串内的对称点,数组d[]的作用 是保存以点i为中心的回文串的长度。也就是说当求d[i]时,对称的d[2*id-i]已经在之前的计算中求出了。便可以直接使用。但是,因为可能出现d[2*id-i]的对称半径超出d[id]的对称半径的情况(即回文串id只包含部分串2*id-i)。所以就只能取mx-i的值(即从i点到串id边缘)。这就是为什么要取最小值的原因。
然后这题只要直接用manacher算法就可以解了,不过....... cin ,strlen() , memset() 这仨千万千万千万不要用,用了就会超时,不要问我为什么...。
代码如下:
#include<iostream>#include<string.h>#include<cstdio>using namespace std;char a[120005];char cmp[250000];int d[250000];void insertchar() //插入分隔符{ int i,l,len; cmp[0] = '@'; for(i=0,l=1;a[i]!=NULL;i++) { cmp[l++] = '#'; cmp[l++] = a[i]; } cmp[l] = '#'; cmp[l+1] = NULL;}int main(){ while(~scanf("%s",a)) { int i,id=0,mx = 0,maxs=0,max2; insertchar(); for(i=1;cmp[i]!=NULL;i++) { if(mx>i) { d[i] = min(mx-i,d[2*id-i]); //判断决定d[i]的最小值 } else d[i] = 1; while(cmp[i+d[i]]==cmp[i-d[i]]) { d[i]++; } if(d[i]+i>mx) //将mx的值延伸至以判断过的回文串的最边缘; { mx = d[i]+i; id = i; } if(d[i]>maxs) { maxs = d[i]; max2 = i; } } cout<<maxs-1<<endl; } return 0;}
以上;
0 0
- Hdu 3068 最长回文 (manacher算法)
- hdu 3068 最长回文 (manacher算法)
- HDU 3068 最长回文(Manacher 算法)
- HDU-3068-最长回文 (Manacher算法)
- hdu 3068 最长回文(manacher算法)
- HDU 3068 最长回文 Manacher算法
- hdu 3068 最长回文 manacher算法
- hdu 3068 最长回文(manacher算法)
- Hdu 3068 最长回文 Manacher 算法
- hdu 3068 最长回文 (Manacher算法)
- HDU 3068 最长回文 (Manacher算法)
- hdu-3068 最长回文 【Manacher算法】
- Hdu 3068 最长回文(manacher算法)
- HDU 3068 最长回文(manacher算法)
- HDU 3068 最长回文 (manacher算法)
- HDU 3068 最长回文(manacher算法模板)
- hdu 3068 最长回文 manacher算法
- [hdu 3068] 最长回文 manacher算法
- 安卓手机开发学习之设置Settings
- Android 内核学习之三-----Power源码分析学习(2)
- dialog 自动弹出软键盘的问题
- HDU 1272详细题解(并查集)
- CGlib简单介绍
- HDU 3068 最长回文 (manacher算法)
- leetCode(54):Gas Station
- 数据结构四:栈的两种形式LinkStack和SeqStack用线性表的实现方式,以及SeqQueue和LinkQueue的实现
- repeater批量排序
- 南邮 OJ 1616 lithium的包裹
- Hdu 5350 MZL's munhaff function 2015ACM多校对抗赛第五场
- iOS之引导页开发(一)——采用NSUserDefaults进行首次运行判断
- Redis——乐观锁控制事务
- spring 注入 和 实例化的差别(别说没区别)