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



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
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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 婴儿胃食道反流怎么办 小儿胃食道反流怎么办 放疗后咳嗽痰多怎么办 胃息肉是恶性的怎么办 老是胃疼,胃胀怎么办 吃完饭之后胃胀怎么办 胃痛胃胀怎么办能缓解 胃胀不消化怎么办快速解决 便秘肛裂了好痛怎么办 胃消化慢还便秘怎么办 11个月婴儿便秘怎么办 80多岁老人便秘怎么办 狗狗便秘拉不出来怎么办 2个月幼犬便秘怎么办 狗狗便秘怎么办吃什么 痔疮又痛又痒怎么办 痔疮肉球特别痒怎么办 长了个小痔疮怎么办 产后4天没大便怎么办 7个月孕妇痔疮怎么办 运动完恶心想吐怎么办 跑步后恶心想吐怎么办 肠子不蠕动严重便秘怎么办 怀孕八个月严重便秘怎么办 怀孕七个月便秘严重怎么办 怀孕两个月便秘严重怎么办 3岁宝宝上火便秘怎么办 7个月的宝宝贫血怎么办 9个月婴儿贫血怎么办 肛裂大便有血怎么办 生完宝宝肛门痛怎么办 肛周脓肿出血了怎么办 胃胀怎么办简单的办法 吃多了胃胀难受怎么办 胃窦炎胆汁反流怎么办 怀孕总胆汁酸高怎么办 胃里胆汁反流怎么办 苦胆水吐出来了怎么办 喝多了吐胆汁怎么办 吐出黄水苦水是怎么办 喝酒喝的一直吐怎么办