欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hihocoder1032最长回文子串 [Manacher]

程序员文章站 2022-07-13 21:56:56
...

1032 : 最长回文子串

时间限制:1000ms
单点时限:1000ms
内存限制:64MB
描述
小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

小Ho奇怪的问道:“什么叫做最长回文子串呢?”

小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

样例输入
3
abababa
aaaabaa
acacdas
样例输出
7
5
3

马拉车水题,注意边界即可

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1001000;

int n,p[N<<1];
char s[N],now[N<<1];
bool ISK(char ch) {return ch==10||ch==13||ch==EOF;}
void readinit(){scanf("%*[^\n]");getchar();}
void readin(int &res){
    static char ch;register int flag=1;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int readchar(char *x){
    int len=0;char ch=getchar();
    if(ch==EOF)return EOF;
    s[++len]=ch;
    while(!ISK(s[len]))s[++len]=getchar();
    s[len--]=0;
    return len;
}
int Manacher(char *s){
    int len=strlen(s+1);
    for(register int i=1;i<=len;i++)now[2*i-1]='#',now[2*i]=s[i];
    now[len=len*2+1]='#',now[0]='+',now[len+1]='-';
    int pos=0,R=0,maxn=0;
    for(register int i=1;i<=len;i++){
        if(i<R)p[i]=min(p[2*pos-i],R-i);
        else p[i]=1;
        while(1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]]==now[i+p[i]])p[i]++;
        if(i+p[i]>R)pos=i,R=i+p[i];
    }
    for(int i=1;i<=len;i++)maxn=max(maxn,p[i]-1);
    return maxn;
}
int main(){
    readin(n);
    while(n--)readchar(s),cout<<Manacher(s)<<endl;
    return 0;
}

hihocoder1032最长回文子串 [Manacher]

相关标签: hihocoder Manacher