hdu 3294 manacher算法

没什么还说的  也就是这一类的裸题吧

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

char str[200010],str1[400010];
int mark[400010];
int min(int a,int b)
{
    return a<b?a:b;
}
int main()
{
    char str2[5];
    int i,j;
    while(~scanf("%s%s",str2,str))
    {
        int len=strlen(str);
        str1[0]=‘$‘;
        j=0;
        for(i=0;i<len;i++)
        {
            str1[++j]=‘#‘;
            if(str[i]>=str2[0])
                str[i]=str[i]-str2[0]+‘a‘;
            else str[i]=26-(str2[0]-str[i])+‘a‘;
            str1[++j]=str[i];
        }
        str1[++j]=‘#‘;
        memset(mark,0,sizeof(mark));
        int right=0,k=0,id,pp;
        for(i=0;i<=j;i++)
        {
            if(right<=i) mark[i]=1;
            else mark[i]=min(mark[2*id-i],right-i);
            while(str1[i+mark[i]]==str1[i-mark[i]])
            mark[i]++;
            if(right<i+mark[i])
            {
                right=i+mark[i];
                id=i;
            }
            if(mark[i]>k)
            {
                k=mark[i];
                pp=i;
            }
        }
        k-=1;
        if(k<=1) printf("No solution!\n");
        else
        {
            if(str1[pp]!=‘#‘)printf("%d %d\n",pp/2-(k-1)/2-1,pp/2+(k-1)/2-1);
            else printf("%d %d\n",(pp-1)/2-(k-1)/2-1,(pp+1)/2+(k-1)/2-1);
            for(i=pp-k+1;i<pp+k;i+=2)
            {
                printf("%c",str1[i]);
            }
            printf("\n");
        }
    }
    return 0;
}
时间: 2024-11-08 22:13:45

hdu 3294 manacher算法的相关文章

HDU 3294 (Manacher) Girls&#39; research

变形的求最大回文子串,要求输出两个端点. 我觉得把'b'定义为真正的'a'是件很无聊的事,因为这并不会影响到最大回文子串的长度和位置,只是在输出的时候设置了一些不必要的障碍. 另外要注意一下原字符串s1中的字符在预处理以后的字符串s2中对应的坐标关系,这样输出的时候就可以照着这个关系转化. 轻松1A,嘿嘿 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5

hdu 3068 Manacher算法 O(n)回文子串算法

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3068 关于算法的教程  推荐这个:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824    注意:我推荐的这篇博客里说的那个代码有bug,我觉得没问题,而是博主在用的时候写错了,博主举得反例我都过了 而且hdu 3068也过了 最开始是用的后缀数组,2000ms+ 果断超时............... 看过一遍很快就学会这个算法了:然后A

HDU 3613(Manacher算法)

题意:字母表的26个字母都有一个价值,给定一个字符串,将该字符串切成两份,对于每一份,如果是回文串,就获得该子串的字母价值之和,否则该子串的价值为0.求出将字符串切成两份后能够获得的最大价值. 做法:先用Manacher算法求出以每个字母为中心的回文串的长度,并计算该字符串的前缀价值和.然后枚举切割点,得到两份子串.这样就可以知道每个子串的中心点,然后检查以该子串的中心点作为中心点的回文串的长度,如果长度等于该子串的长度,那么就加上该子串的价值.然后和最优价值比较就行了. 其实如果熟悉了Mana

hdu 3068 Manacher算法

题意:求最长回文串,模板题 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=

hdu 3294 manacher 求回文串

感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位置i的答案时,利用已经算出的1~i-1位置的答案. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define maxn 222222 5 using namespace std; 6 7

HDU 3294 Girls&#39; research (Manacher算法 + 记录区间)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3294 题目大意:输入一个字符ch和一个字符串,问如果把ch当作'a'的话,字符串的每个字符也要做相应变化,如b aa,若b为'a',则b前面的a就为'a'前面的'z',这里是循环表示,输出字符串的最长回文子串,如果最长回文子串串长为1,输出No solution! 几乎是模板题,唯一的特别之处就是要输出回文串字符,所以要记录max(Mp[i])对应的在原串中的字符区间,根据Manacher算法的步骤

Manacher 算法(hdu 3068 &amp;&amp; hdu 3294)

今天打算补前晚 BC 的第二题,发现要用到能在 O(n) 时间求最大回文子串长度的 Manacher 算法,第一次听,于是便去百度了下,看了大半天,总算能看懂了其思想,至于他给出的代码模板我没能完全看懂,只好自己试着实现,发现理解了思想后还是能实现出来的,用自己的风格去写更好理解,先附上讲解 Manacher 算法的几个链接: Manacher算法--O(n)回文子串算法 (我就是看这个理解的~) Manacher算法处理字符串回文 hdu3068之manacher算法+详解 浅谈manache

Hdu 3294 Girls&#39; research (manacher 最长回文串)

题目链接: Hdu 3294  Girls' research 题目描述: 给出一串字符串代表暗码,暗码字符是通过明码循环移位得到的,比如给定b,就有b == a,c == b,d == c,.......,a == z. 问最长回文串所在区间,以及最长回文串所表示的明码. 解题思路: 字符串长度[1,200000],用manacher算法很轻松就搞定了. get√新技能请点击me 1 #include <cstdio> 2 #include <cstring> 3 #includ

HDU 3068 最长回文 (manacher算法)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9188    Accepted Submission(s): 3159 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组