• kuangbin专题十六 KMP&&扩展KMP HDU3068 最长回文


    给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
    回文就是正反读都是一样的字符串,如aba, abba等

    Input输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
    两组case之间由空行隔开(该空行不用处理)
    字符串长度len <= 110000Output每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
    Sample Input
    aaaa
    
    abab
    Sample Output
    4
    3


    马拉车裸题。
    再次学习马拉车

    第一步:字符串预处理,保证长度都为奇数。
    明确id,mx的含义 id为最远回文对应的中心位置,mx为最远回文位置
    用p[i]记录以i为中心的最大回文半径

    第二步:求p[i]

    分两种情况:
    一、mx > i


    ①,mx-i>p[i]

    如图所示:红色部分为i的回文范围。i和j关于id对称。说明p[i]=p[j]=p[2*id-i]


    ②,mx-i<=p[i]

    如图所示,红色为中心为i的回文范围,如果i+p[i]>mx, 那么只能说明 mx-i 这一段是可以由之前的推出来的
    因为 mx是以id为中心,对应最远的回文右边界。所以这种情况p[i]=mx-i


    二、mx<=i

    说明根本不知道以后的情况,只能p[i] = 1


     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<string.h>
     4 using namespace std;
     5 char s[110010],snew[220010];
     6 int p[220010];
     7 
     8 int manacher(char* s) {
     9     int l=0;
    10     snew[l++]='$';
    11     snew[l++]='#';
    12     for(int i=0;s[i];i++) {
    13         snew[l++]=s[i];
    14         snew[l++]='#';
    15     }
    16     snew[l]='';
    17     int id=0,mx=0,maxlen=-1;
    18     for(int i=0;i<l;i++) {
    19         p[i]=i<mx?min(p[2*id-i],mx-i):1;
    20         while(snew[i+p[i]]==snew[i-p[i]]) p[i]++;
    21         if(i+p[i]>mx) {
    22             mx=i+p[i];
    23             id=i;
    24         }
    25         if(p[i]>maxlen) maxlen=p[i]-1;
    26     }
    27     return maxlen;
    28 }
    29 
    30 int main() {
    31     while(~scanf("%s",s)) {
    32         printf("%d
    ",manacher(s));
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    232. Implement Queue using Stacks
    231. Power of Two
    n&(n-1)位运算的妙用
    230. Kth Smallest Element in a BST
    关于UNIX的exec函数
    Go语言的各种Print函数
    Go语言的接口interface、struct和组合、继承
    Go语言知识点笔记
    Ubuntu自定义终端窗口位置
    Python的类变量和成员变量、类静态方法和类成员方法
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/10325382.html
Copyright © 2020-2023  润新知