HDU

来源:互联网 发布:linux if语句的用法 编辑:程序博客网 时间:2024/06/05 10:32

点我看题

题意:给一个字符和一个串,根据一定的规则变换串,然后找出最长回文子串并输出串最右两端的下标。

分析:manacher模板题,在求解下标的时候利用到manacher最基本的性质—变换后的字符串的回文子串都是奇数,然后可以很顺利的找出manacher的下标。

参考代码:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define INF 0x3f3f3f3fconst int maxn = 2e5+100;int n;char ch;char s[maxn<<1];int p[maxn<<1];void manacher(){    memset(p,0,sizeof(p));    for( int i = n; i >= 0; i--)    {        s[i*2+2] = s[i];        s[i*2+1] = '#';    }    s[0] = '$';    int id, mx = 0;    for( int i = 1; i < 2*n+1; i++)    {        if( i < mx)            p[i] = min(p[2*id-i],mx-i);        else            p[i] = 0;        while( s[i-p[i]] == s[i+p[i]])            p[i]++;        if( i+p[i] > mx)        {            mx = i+p[i];            id = i;        }    }}int main(){    while( ~scanf("%c%s",&ch,s))    {        n = strlen(s);        int d = ch-'a';        for( int i = 0; i < n; i++)            s[i] = (s[i]-'a'-d+26)%26+'a';        manacher();        int id = -1, mx = -INF;        for( int i = 1; i < 2*n+1; i++)            if( p[i] > mx)                mx = p[i], id = i;        mx--;        int tmp = mx/2;//前面或后面有多少个字母在回文中        if( tmp)        {            int l = id-mx+1;            int r = id+mx-1;            printf("%d %d\n",(l-2)/2,(r-2)/2);            for( int i = l; i <= r; i++)                if( s[i] != '#')                    printf("%c",s[i]);            puts("");        }        else            puts("No solution!");        getchar();    }    return 0;}


原创粉丝点击