程序改变世界,教育改变未来

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

题目大意:有多组数据,每组数据给出一个字符和一个字符串。该字符将变成’a‘,表示字符串中的所有该字符将变成’a‘,同时其他字符也将做相同的偏移。具体来说,如果该字符为’b‘,表示字符串中的’b‘都将变成a,偏移量为-1。此时字符串的其他字符都要做这个偏移,比如c将变成‘b’,'d'将变成‘c’……,而‘a’将变成‘z’。

现在给出许多这样的数据,要求出转换过后的最长的回文串。

分析:求回文串用manacher算法。因为manacher中会插入字符,从而改变原来的字符的位置。所以输出位置时要小心处理。一开始搞错了,位置多减了一个1,却过了样例和自己出的几个小数据。一定要多测试一些数据才行。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 400005
char s1[MAXN],s2[MAXN];
char str[3];
int p[MAXN],maxid,ans=0,pos;
void manacher(char *s)
{
    int len=strlen(s);
    p[0]=1,maxid=0;
    for(int i=1;i<len;++i)
    {
         if(maxid+p[maxid]>i)
          p[i]=min(p[2*maxid-i],maxid+p[maxid]-i);
        else p[i]=1;
        for(;s[i+p[i]]==s[i-p[i]];p[i]++);
        if(p[i]+i>p[maxid]+maxid)maxid=i;
    }
    }
int main()
{
    while(scanf("%s %s",str,s1)!=-1)
    {
        int len=strlen(s1);
        ans=0;
        pos=0;
        memset(s2,0,sizeof s2);
        s2[0]='*';
        s2[1]='#';
        for(int i=0,j=2;i<len;i++)
        {
            s2[j++]=s1[i];
            s2[j++]='#';
        }
        manacher(s2);
        len=strlen(s2);
        for(int i=0;i<len;i++)
        {
            if(p[i]>ans)
            {ans=p[i];
             pos=i;
            }
        }
        if(ans<=2)
        {printf("No solution!\n");
         continue;
        }
        pos-=(ans-1);
        pos=(pos-1)/2;
        
        printf("%d %d\n",pos,pos+ans-2);
        for(int i=pos;i<pos+ans-1;i++)
        {
            s1[i]-=(str[0]-'a');
            if(s1[i]<'a')
                s1[i]+=26;
            printf("%c",s1[i]);
        }
        printf("\n");        
        }
    }

 

posted on 2015-12-19 11:53  hefenghhhh  阅读(256)  评论(0编辑  收藏  举报