hdu 3294

题目

题意有点难理解,意思就是先给你一个字符变换规则,然后求出变换后的字符串的最长回文字串。

首先这题要求我们理解manacher算法,p[i]代表什么等。我们可以在确定最长长度的时候记录位置,因为p[i]记录的是以i为中心的最长回文半径,所以就(pos±p[i]±1)/2就可以了。因为manacher会在字符串的每个字符前面上加标记,所以要/2。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#include<cmath>
#include<map> 
#include<string>
#include<queue>
#include<stack> 
#include<bitset>
#include<list>
#define IO ios::sync_with_stdio(false)
#define int long long
using namespace std;
char s[200005],ns[200005<<1],c;
int len,nlen,p[200005<<1],pos;
int manacher()
{
    memset(p,0,sizeof(p));
    memset(ns,0,sizeof(ns));
    pos=0;
    ns[0]='$';
    ns[1]='#';
    int j=2;
    for(int i=1;i<=len;i++)
    {
        ns[j++]=s[i];
        ns[j++]='#';
    }
    ns[j]='\0';
    nlen=j;
    int maxlen=-1,id,mx=0;
    for(int i=1;i<=nlen;i++)
    {
        if(i<mx)
        {
            p[i]=min(p[2*id-i],mx-i);
        }
        else
        {
            p[i]=1;
        }
        while(ns[i-p[i]]==ns[i+p[i]])p[i]++;
        if(mx<i+p[i])
        {
            id=i;
            mx=i+p[i];
        }
        if(p[i]-1>maxlen)
        {
            maxlen=p[i]-1;
            pos=i;
        }
    }
    return maxlen;
}
signed main()
{
    IO;
    while(cin>>c>>s+1)
    {
        int x=c-'a';
        len=strlen(s+1);
        for(int i=1;i<=len;i++)
        {
            int wei=s[i]-'a';
            wei-=x;
            s[i]='a'+(26+wei)%26;
        }
        int ans=manacher();
        if(ans==1)
        {
            cout<<"No solution!"<<endl;
            continue;
        }
        int xx=(pos-ans+1)/2,yy=(pos+ans-1)/2;
        cout<<xx-1<<" "<<yy-1<<endl;
        for(int i=xx;i<=yy;i++)
        {
            cout<<s[i];
        }
        cout<<endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值