Manacher算法练习

入门
http://acm.hdu.edu.cn/showproblem.php?pid=3068
没什么好解释的,裸题

#include<iostream>
#include<algorithm>
#define maxn 110010*2
using namespace std;
char s[maxn];
int p[maxn];
char a[maxn];
void init()
{
    int i,j=2;
    s[0]='$';
    s[1]='#';
    for(i=0;a[i];i++)
    {
        s[j++]=a[i];
        s[j++]='#';
    }
    s[j]='\0';
}
void solve()
{
    int i,id=0,mx=0;
    p[0]=0;
    for(i=1;s[i];i++)
    {
        if(mx>i)
            p[i]=min(p[2*id-i],mx-i);
        else
            p[i]=1;
        while(s[i+p[i]] == s[i-p[i]])
            p[i]++;
        if(mx<p[i]+i)
        {
            mx = p[i]+i;
            id = i;
        }
    }
}
int main()
{
    while(scanf("%s",a)!=EOF)
    {
        init();
        solve();
        int ans = 0;
        for(int i=1;s[i];i++)
        {
            ans = max(ans,p[i]);
        }
        printf("%d\n",ans-1);
    }
    return 0;
}

基础
http://acm.hdu.edu.cn/showproblem.php?pid=3294

#include<iostream>
#include<algorithm>
#include<cstring>
#define maxn 200010*2
using namespace std;
char ch[26];
char s[maxn];
char s2[maxn];
int p[maxn];
int ans=0;

//基本操作
void init()
{
    int i,j=2;
    s2[0]='$';
    s2[1]='#';
    for(i=0;s[i];i++)
    {
        s2[j++] = s[i];
        s2[j++] = '#';
    }
    s2[j]='\0';
}
//基本操作
void solve()
{
    int i,mx=0,id=0;
    p[0]=0;
    for(i=1;s2[i];i++)
    {
        if(mx>i)
            p[i] = min(p[2*id-i],mx-i);
        else
            p[i]=1;
        while(s2[i+p[i]] == s2[i-p[i]])
            p[i]++;
        if(mx<p[i]+i)
        {
            mx = p[i]+i;
            id = i;
        }
        //基本操作
        if(p[i]>p[ans])
            ans = i;
    }
}
int main()
{
    int i;
    for(i=0;i<26;i++)
    {
        ch[i]='a'+i;
    }
    char c1[3];
    while(scanf("%s%s",c1,s)!=EOF)//%c处理起来麻烦死了,所以改成%s
    {
        ans=0;
        for(i=0;s[i];i++)
        {
            s[i]=ch[(s[i]-c1[0]+26)%26];
        }
//      cout<<s<<endl;
        init();
        solve();
        if(p[ans]>2){
//          cout<<p[ans]<<endl;
            int start = (ans-1)/2;//第i个字符前面插入了i个#(除去第一个$符号) 所以减一
            start =start-(p[ans]-1)/2;//p[ans] - 1 是真实回文长度
            int end = start+p[ans]-2;//0 ~p[ans]-2  p[ans]-1个字符 也就是回文长度
            cout<<start<<" "<<end<<endl;
            for(i=start;i<=end;i++)
                cout<<s[i];
            cout<<endl;
        }
        else
        {
            cout<<"No solution!"<<endl;
        }
    }
    return 0;
}

待续^-^

猜你喜欢

转载自blog.csdn.net/qq_36734025/article/details/80674664