【HDU3294,URAL1294】manacher算法

来源:互联网 发布:spycall是什么软件 编辑:程序博客网 时间:2024/04/29 04:35

manacher算法用于计算最长回文子串。
上模板

    //s是原子符串,而w是在s的前面、后面、字符之间插入一个未出现的字符‘#’    scanf("%s",s);    w[0]='*';//防止越界,在最前面加上一个‘*’    w[++len]='#';    for(int tmp=strlen(s), i=0;i<tmp;++i)    {        w[++len]=s[i];        w[++len]='#';    }    --len;    //p[i]表示以i为中心向左右扩展的最长回文子串的长度    p[1]=ans=maxd=1;    for(int i=2;i<len;++i)    {        if(p[maxd]+maxd>i)p[i]=min(p[maxd+maxd-i],maxd+p[maxd]-i);        else p[i]=1;        while(w[i+p[i]]==w[i-p[i]])++p[i];        if(ans<p[i])ans=p[i];        if(maxd+p[maxd]<p[i]+i)maxd=i;    }    printf("%d\n",ans-1);

而HDU3294,URAL1297为manacher的裸题。

URAL1297:
题意:求一个字符串的最长回文子串

#include <cstdio>#include <cstring>#define MAXN 100005#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))using namespace std;char s[MAXN], a, w[MAXN];int len, p[MAXN], maxd, ans;int main(){    //freopen("data.txt","r",stdin);    scanf("%s",w);    s[0]='*', s[++len]='#';    for(int tmp=strlen(w), i=0;i<=tmp;++i)    {        s[++len]=w[i];        s[++len]='#';    }    --len;    p[1]=ans=1, maxd=1;    for(int i=2;i<len;++i)    {        if(p[maxd]+maxd>i)p[i]=min(p[maxd+maxd-i],p[maxd]-i+maxd);        else p[i]=1;        while(s[i+p[i]]==s[i-p[i]])++p[i];        if(p[maxd]+maxd<p[i]+i)maxd=i;        if(p[ans]<p[i])ans=i;    }    for(int i=ans-p[ans]+1, tmp=p[ans]-1;i<len&&tmp;++i)    {        if(s[i]=='#')continue;        printf("%c",s[i]);        --tmp;    }    return 0;}

HDU3294:
题目链接
题意:将某一字符串先向左平移若干个单位(第一个字符-‘a’)。求最先出现的最长回文子串的起始位置、结束位置,并输出。

一开始以为第一个字符只会是’a’或’b’,然后就wa了几遍…

#include <iostream>#include <cstdio>#include <cstring>#define MAXN 400050using namespace std;char ask[5], s[MAXN], w[MAXN];int len, p[MAXN], ans, maxd;int main(){    while(~scanf("%s",ask))    {        len=0;        scanf("%s",s);        w[0]='*';        w[++len]='#';        for(int tmp=strlen(s), i=0;i<=tmp;++i)        {            w[++len]=s[i];            w[++len]='#';        }        len-=2;        p[1]=ans=1, maxd=1;        for(int i=2;i<len;++i)        {            if(p[maxd]+maxd>i)p[i]=min(p[maxd+maxd-i],p[maxd]+maxd-i);            else p[i]=1;            while(w[i+p[i]]==w[i-p[i]])++p[i];            if(p[i]+i>p[maxd]+maxd)maxd=i;            if(p[ans]<p[i])ans=i;        }        if(p[ans]<3)puts("No solution!");        else        {            int Begin=(ans-p[ans]+2)/2-1, End=(ans+p[ans]-2)/2-1, k=ask[0]-'a';            printf("%d %d\n",Begin,End);            for(;Begin<=End;++Begin)                printf("%c",(s[Begin]-'a'-k+26)%26+'a');            puts("");        }    }    return 0;}
0 0
原创粉丝点击