zoukankan      html  css  js  c++  java
  • hdu 3068 最长回文 (Manacher算法求最长回文串)

    参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET

      从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度。这个算法好像比较偏门,不过还是稍微掌握一下会比较好。

      其实,我的理解就是,记录当前知道找到的最长的回文串的中心以及向右延伸后的最右端点位置。然后其中找最长回文串的操作其实还是暴力的,只不过这样记录两个位置以及覆盖了区间以后,下次我们要找的最长回文串的时候就可以借助这个已知信息减少大量的冗余查找。至于怎么证明这个剪枝可以使算法达到O(N)的复杂度,还是找资料比较好。

    用hdu 3068这题测试,340ms通过:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <ctime>
     6 
     7 using namespace std;
     8 
     9 const int N = 111111;
    10 char str[N], nstr[N << 1];
    11 int p[N << 1];
    12 
    13 int manacher(char *s) {
    14     int id = 0, lf = 0, len = strlen(s), mx = 1;
    15     p[0] = 1;
    16     for (int i = 1; i < len; i++) {
    17         if (lf > i) p[i] = min(p[(id << 1) - i], lf - i);
    18         else p[i] = 1;
    19         while (s[i + p[i]] && s[i + p[i]] == s[i - p[i]]) p[i]++;
    20         if (lf < i + p[i] - 1) lf = i + p[i] - 1, id = i;
    21         mx = max(p[i], mx);
    22     }
    23     return mx - 1;
    24 }
    25 
    26 int main() {
    27     while (~scanf("%s", str)) {
    28         char *p = str, *q = nstr;
    29         while (true) {
    30             *(q++) = '~', *(q++) = *p;
    31             if (!*p) break;
    32             p++;
    33         }
    34         //cout << nstr << endl;
    35         cout << manacher(nstr) << endl;
    36     }
    37     return 0;
    38 }
    View Code

    ——written by Lyon

  • 相关阅读:
    E-R图转换成关系模型
    折叠表格
    ICE在Linux下的安装
    yum 安装gcc
    dll和so文件区别与构成
    linux进入图形界面的方法
    ACE vs Boost: Singleton的实现
    ACE与ASIO之间关于Socket编程的比较
    Linux 下编译安装ACE时遇到的问题及解决
    Linux下安装、配置ACE
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3068_Lyon.html
Copyright © 2011-2022 走看看