hdu3294+Manacher算法

                                                         Girls' research
Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1027    Accepted Submission(s): 389

Problem Description
 

One day, sailormoon girls are so delighted that they intend to research about palindromic strings. Operation contains two steps:
First step: girls will write a long string (only contains lower case) on the paper. For example, "abcde", but 'a' inside is not the real 'a', that means if we define the 'b' is the real 'a', then we can infer that 'c' is the real 'b', 'd' is the real 'c' ……, 'a' is the real 'z'. According to this, string "abcde" changes to "bcdef".
Second step: girls will find out the longest palindromic string in the given string, the length of palindromic string must be equal or more than 2.
 

Input
 

Input contains multiple cases.
Each case contains two parts, a character and a string, they are separated by one space, the character representing the real 'a' is and the length of the string will not exceed 200000.All input must be lowercase.
If the length of string is len, it is marked from 0 to len-1.

Output
 

Please execute the operation following the two steps.
If you find one, output the start position and end position of palindromic string in a line, next line output the real palindromic string, or output "No solution!".
If there are several answers available, please choose the string which first appears.
 

Sample Input
 

b babd a abcd
 

Sample Output
 

0 2 aza No solution!
 

Author
 

wangjing1111
 

Source
 

2010 “HDU-Sailormoon” Programming Contest

题意,先将给定串转换,得到的串中寻找最长回文串

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
char zimu[100]= {'\0'};
struct point
{
    int le,ri;
}p;
int len[400066];
point malache(char  ss[400004])
{

    int idr=0;
    int rmax=0;
   char s2[400066];
   s2[0]='$';
   s2[1]='#';
   int k=2;
   int len1=strlen(ss);
    for(int i=0;i<len1;i++)
    {
        s2[k++]=ss[i];
        s2[k++]='#';
    }
    s2[k]='\0';
  //  cout<<s2<<endl;
    int maxid=0;
    int maxrr=0;
    int i=1;
    //马拉车算法(求解一个串中最长回文串相关信息)
    while(i<k)
    {
        if(i<=rmax)len[i]=min(rmax-i+1,len[2*idr-i]);//看看关于右括号对应的中心点的对称点的半径对应的边界是否超过了左括号的位置,超过了则取到左括号,没超过则该点的半径就是对称点的半径
        else len[i]=1;
        while(s2[i-len[i]]==s2[i+len[i]])
        {
            len[i]++;
        }
        if(i+len[i]-1>rmax)
        {
            rmax=i+len[i]-1;
            idr=i;
            if(len[i]>maxrr)
            {
                maxrr=len[i];
                maxid=idr;
            }
        }
        i++;
    }

     int le=-1;
     int ri=-1;
     int h=0;
     //找到原始回文串的位置
     for(int i=maxid-maxrr+1;i<=maxid+maxrr-1;i++)
     {
         if(i%2==0)
         {
             if(le==-1)le=i/2-1;
             ri=i/2-1;
         }
     }
     p.le=le;
     p.ri=ri;
     return p;
}
int main()
{
    for(int i=0; i<26; i++)
    {
        zimu[i]='a'+i;
        // cout<<zimu[i]<<endl;
    }
    char c;
    char  s[400004];
    while(~scanf("%c",&c))
    {
        scanf("%s",s);
        getchar();
        int cha=c-'a';
        int len=strlen(s);
       // cout<<s<<" " <<len<<endl;
       //将字符数组转成找回文串的目标字符数组组
        for(int i=0; i<len; i++)
        {
            int bi=(s[i]-'a'+26-cha)%26;
            s[i]=zimu[bi];
        }
     point pp=malache(s);
     if(pp.ri-pp.le==0)
     {
         printf("No solution!\n");
     }
     else
     {
         printf("%d %d\n",pp.le,pp.ri);
         for(int i=pp.le;i<=pp.ri;i++)
         {
             printf("%c",s[i]);
         }
         printf("\n");
     }
    }
}


 
 

猜你喜欢

转载自blog.csdn.net/wrwhahah/article/details/83958192
今日推荐