zoukankan      html  css  js  c++  java
  • 最长回文字串(hdu 3068)

    原题链接http://acm.hdu.edu.cn/showproblem.php?pid=3068

    查找字符串中最长的回文串,我们用到manachar算法。

    要实现manachar算法我们有有两步要做

    1:对字符串进行处理,把所有的字符串的长度统一化为奇数。。

     1  int l=0;
     2     int ans=0;
     3     Ma[l++]='$';
     4     Ma[l++]='#';
     5     for(int i=0;i<len;i++)
     6     {
     7         Ma[l++]=s[i];
     8         Ma[l++]='#';
     9     }
    10     Ma[l]=0;

    例如abbba这个字符串经过处理后就变成了

    $#a#b#b#b#a#

    然后我们用的Mp[]表示以i为中心的(包含i这个字符)回文串半径长,然后我们就要去求Mp数组的值

    假设我们扫到i+k这个位置,那么我们现在需要计算Mp[i+k],

    若s[i+k]不在前面任何一个回文串中,MP[i+k]=1;

    然后s[i+k]左右延伸

    
    
     while(Ma[i-Mp[i]]==Ma[Mp[i]+i]) Mp[i]++;
    若是s[i+k]在之前的回文串中那么Mp[s+k]就不是从1开始了,而且Mp[i]数组有一个最小值
    我们设j=2*id-i;j是i关于id的对称点,下图中p数组就是Mp数组

     综上所述Mp[i]=min(Mp[2*id-i],mx-i);

     
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 const int maxn=110000;
     6 char s[maxn];
     7 char Ma[maxn*2];
     8 int Mp[maxn*2];
     9 using namespace std;
    10 int manachar(int len)
    11 {
    12     int l=0;
    13     int ans=0;
    14     Ma[l++]='$';
    15     Ma[l++]='#';
    16     for(int i=0;i<len;i++)
    17     {
    18         Ma[l++]=s[i];
    19         Ma[l++]='#';
    20     }
    21     Ma[l]=0;
    22     int mx=0,id=0;
    23     for(int i=0;i<l;i++)
    24     {
    25         if(mx>i)
    26         Mp[i]=min(Mp[2*id-i],mx-i);
    27         else
    28         Mp[i]=1;
    29         while(Ma[i-Mp[i]]==Ma[Mp[i]+i]) Mp[i]++;
    30         if(i+Mp[i]>mx)
    31         {
    32             mx=i+Mp[i];
    33             id=i;
    34         }
    35         ans=max(ans,Mp[i]-1);
    36     }
    37     return ans;
    38 } 
    39 int main()
    40 {
    41     while(scanf("%s",s)!=EOF)
    42     {
    43         int len=strlen(s);
    44         int ans=manachar(len);
    45         printf("%d
    ",ans);
    46     }
    47     return 0;
    48 } 
    
    

    完整的AC代码

                
    
  • 相关阅读:
    Redis 持久化
    Redis 事务
    select poll和 epoll
    jdk信任证书
    Java中的锁分类
    mysql触发器同步远程服务器上数据库
    正则表达式
    mysql主从同步
    MySQL逗号分割字段的行列转换技巧
    Mysql中文排序
  • 原文地址:https://www.cnblogs.com/NaCl/p/9580174.html
Copyright © 2011-2022 走看看