zoukankan      html  css  js  c++  java
  • hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]

    传送门

    #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

    题解:

     Manacher算法--O(n)回文子串算法

    直接转一个大牛的思路,讲的很好:

    http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/

    http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=140283

    结果:Accepted      提交时间:2015-05-07 14:11:06

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <stack>
     6 #include <cctype>
     7 #include <vector>
     8 #include <cmath>
     9 
    10 #define ll long long
    11 
    12 using namespace std;
    13 
    14 const int M = 21;
    15 const int N = 1000010;
    16 const ll mod = 1000000007;
    17 
    18 int T;
    19 char te[N];
    20 char s[2*N];
    21 int p[2*N];
    22 int ans;
    23 int l;
    24 
    25 void pre()  //为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的
    26 {
    27     int l1=strlen(te);
    28     l=2*l1+2;
    29     s[0]='$';
    30     s[1]='#';
    31     for(int i=0;i<l1;i++){
    32         s[i*2+2]=te[i];
    33         s[i*2+3]='#';
    34     }
    35     s[l]='';
    36 }
    37 
    38 void Manacher()
    39 {
    40     int i,mx,id;    //我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。
    41     mx=0;
    42     for(i=1;i<l;i++){
    43         if(mx>i){
    44             p[i]=min(p[2*id-i],mx-i);
    45         }
    46         else{
    47             p[i]=1;
    48         }
    49         for(;s[ i+p[i] ]==s[ i-p[i] ];p[i]++){
    50             if(i+p[i]>mx){
    51                 mx=i+p[i];
    52                 id=i;
    53             }
    54         }
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     //freopen("data.in","r",stdin);
    61     scanf("%d",&T);
    62     for(int ccnt=1;ccnt<=T;ccnt++){
    63     //while(scanf("%d%d",&a,&b) != EOF) {
    64         scanf("%s",te);
    65         pre();
    66         Manacher();
    67         int i;
    68         ans=1;
    69         for(i=1;i<l;i++){
    70             ans=max(ans,p[i]-1);
    71         }
    72         printf("%d
    ",ans);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    Activity跳转动画
    如何查询自己的手机版本?欧版、亚太、港行、还是国行?
    VC程序员常用工具汇总
    陈灯可重用代码段管理器VS插件版5.0发布(代码段收集器、个人代码库、代码片段管理、代码管理)
    基于OSLC的系统集成
    安桌点菜源代码
    eclipse jsp 文字设置
    ubuntu 下 netbeans平台 使用C连接mysql
    使用gdi+实时绘制picturebox(画个叉)
    思路上的转变,运用投影和一阶导数的思想
  • 原文地址:https://www.cnblogs.com/njczy2010/p/4484765.html
Copyright © 2011-2022 走看看