HDU---3294:Girls' research【最长回文串--Manacher】

题意:

求一个字符串的最长回文串,并输出回文串

分析:

先根据规则处理原串:s[i] = (s[i] - 'a' - (c - 'a') + 26) % 26 +'a'

跑manacher时,记录最长半径的中心点pos,根据转换规律找到最长回文串在原串的【l,r】

代码:

#include 
#include 
#include 
using namespace std;
const int MAXN = 2e5+25;
char s[MAXN],t[MAXN<<1];
int len[MAXN<<1];
int init(char c)
{
    int LEN = strlen(s);
    int v = c - 'a';
    for(int i = 0; i < LEN; ++i)
    {
        s[i] = (s[i] - 'a' - v + 26) % 26 +'a';
    }
    int k = 0;
    t[0] = '{';
    for(int i = 0; i < LEN ; ++i)
    {
        t[++k] = '#';
        t[++k] = s[i];
    }
    t[++k] = '#';
    t[++k] = '}';
    return k;
}
void manacher(char c)
{
    int k = init(c);
    int pos,id = 0,res = 0,mx = 0;
    for(int i = 1; i < k; ++i)
    {
        if(i < mx) len[i] = min(mx-i,len[2*id - i]);
        else len[i] = 1;
        while(t[i + len[i]] == t[i - len[i]]) len[i]++;
        if(i + len[i] > mx)
        {
            id = i;
            mx = i+ len[i];
        }
        if(len[i] > res)
        {
            res = len[i];
            pos = i;
        }
    }
    if(res-1<2) puts("No solution!");
    else{
        int l = pos - (res-1) + 1;
        l = l/2 - 1;
        int r = l + res - 2;
        printf("%d %d\n",l,r);
        for(int i = l; i <= r; ++i)
            putchar(s[i]);
        puts("");
    }
}
int main()
{
    char c;
    while(cin>>c)
    {
        scanf("%s",s);
        manacher(c);
    }
    return 0;
}

 

你可能感兴趣的:(字符串----Manacher)