zoukankan      html  css  js  c++  java
  • hihocoder #1032 : 最长回文子串【 manacher算法实现 】

    #1032 : 最长回文子串

    时间限制:1000ms
    单点时限:1000ms
    内存限制:64MB

    描述

       小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

       这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

       小Ho奇怪的问道:“什么叫做最长回文子串呢?”

       小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

       小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

       小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

    提示一 提示二 提示三 提示四
    样例输入
    3
    abababa
    aaaabaa
    acacdas
    样例输出
    7
    5
    3
    
    代码:
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N = 1010005;
    char str[N], cpy[N<<1];
    int seq[N<<1];
    
    void handle(char *str)
    {
        int len = strlen(str);
        cpy[0] = '(', cpy[1] = '#';
        for (int i=0, j=2; i < len; ++i, j+=2)
        {
            cpy[j] = str[i];
            cpy[j+1] = '#';
        }
        len = len*2+3;
        cpy[len-1] = ')';
    }
    
    void manacher(char s[], int length, int rad[])
    {
        for (int i=1,j=0,k; i < length; i+=k)
        {
            while (s[i-j-1] == s[i+j+1]) ++j;
            rad[i] = j;
            for (k = 1; k <= rad[i] && rad[i-k] != rad[i]-k; ++k)   // 利用类似镜像的方法缩短了时间
            {
                rad[i+k] = min(rad[i-k], rad[i]-k);
            }
            j = max(j-k, 0);
        }
    }
    
    int main()
    {
        int t;
        scanf("%d%*c", &t);
        while (t--)
        {
            scanf("%s", str);
            int len = strlen(str);
            cpy[0] = '(', cpy[1] = '#';
            for (int i=0, j=2; i < len; ++i, j+=2)
            {
                cpy[j] = str[i];
                cpy[j+1] = '#';
            }
            len = len*2+3;
            cpy[len-1] = ')';
    
            manacher(cpy, len, seq);
            int Max = 1;
            for (int i = 0; i < len; ++i)
            {
                Max = max(Max, seq[i]);
            }
            printf("%d
    ", Max);
        }
        return 0;
    }
    
  • 相关阅读:
    空间解析几何与向量代数(复习笔记)
    OpenGL数据类型
    Symbian c++ 调用标准C产生内存泄露
    symbian c++调用标准c函数方法
    (转载)一篇对理解OpenGL的描述的文章
    (个人摘要)make工具的用法
    (转载)哈佛大学凌晨4点半的景象
    网页抓取中的debug 问题记录
    split 使用
    三、抽象工厂(Abstract Factory)模式
  • 原文地址:https://www.cnblogs.com/yspworld/p/4548952.html
Copyright © 2011-2022 走看看