• HDU 3068 最长回文 manacher 算法,基本上是O(n)复杂度


    下面有别人的比较详细的解题报告:

    http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html

    下面贴我的代码,注释在代码中:

     1 #include <cstdio>
     2 #include <cstring>
     3 #define N 110005
     4 char a[N];
     5 char s[N<<1];
     6 int p[N<<1];
     7 int min(int a,int b)
     8 {
     9     return a<b?a:b;
    10 }
    11 int main()
    12 {
    13 //    freopen("out.cpp","r",stdin);
    14     s[0] = '#';
    15     while(scanf("%s",a) != EOF)
    16     {
    17         int len = strlen(a);
    18         int k=1;
    19         //在原字符串两个字符之间插入字符'*',左右两边也各插一个
    20         //这样求回文时只需要求奇数个数的回文
    21         for(int i=0; i<len; ++i)
    22         {
    23             s[k++] = '*';
    24             s[k++] = a[i];
    25         }
    26         s[k++] = '*';
    27         int n = 2*len +1;
    28         int max =0; //当以某个字符为中心求回文时延伸到右边最远的位置的序号
    29         int d;//上面最远位置对应的中心位置
    30         int ans =0;//记录最长回文串的长度
    31         for(int i=1; i <= n; ++i)
    32         {
    33             if(max > i)
    34                 p[i] = min(max-i,p[2*d-i]); //一条线段,以位置d为中心,左边是j
    35                 //右边是i,这样有i+j = 2*d , j = 2*d-i;这里是核心,避免了重复计算,类似记忆化搜索
    36             else
    37                 p[i] = 1;
    38             while( s[i-p[i]] == s[i+p[i]] )  ++p[i];//小技巧,给字符串的最前面添加一个特殊字符,避免数组越界,而不是去判断
    39             if(i+p[i] > max)
    40             {
    41                 max = i+p[i];
    42                 d = i;
    43             }
    44             if(p[i] > ans) ans = p[i];
    45         }
    46         printf("%d
    ",ans-1);
    47     }
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    应该做什么样的研究:以Google为例
    机器学习问题方法总结
    浅析PageRank算法
    轮廓处理函数详细
    近视恢复方法
    一步一步深入视频接口
    什么是cookie
    Linux系统目录数和文件数限制
    九大视频接口全接触
    实时监控网卡流量的命令
  • 原文地址:https://www.cnblogs.com/allh123/p/3230273.html
Copyright © 2020-2023  润新知