zoukankan      html  css  js  c++  java
  • Manacher算法 求最长回文子串

    Manacher

    引例:P3805 【模板】manacher算法(https://www.luogu.org/problem/P3805)

    题目描述

    给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.

    字符串长度为n

    输入格式

    一行小写英文字符a,b,c...y,z组成的字符串S

    输出格式

    一个整数表示答案

    输入输出样例

    输入 #1
    aaa
    输出 #1
    3

    说明/提示

    字符串长度len <= 11000000

    前为老板的标程int代码

    后为网上巨佬的void代码

     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 using namespace std; 
     4 char st[51000100],s[51000100];
     5 int R[51000100];
     6 int Init()
     7 {
     8     int len = strlen(st);
     9     s[0] = '@';
    10     s[1] = '#';
    11     int j = 2;
    12     for (int i = 0; i < len; i++)
    13     {
    14         s[j++] = st[i];
    15         s[j++] = '#';
    16     }
    17     s[j] = ''; // 末尾添字符串结束符
    18     return j; // 返回修改后的字符串的长度
    19 }
    20 int Manacher()
    21 {
    22     int len = Init(); // 在原串中插入特殊符号,并得到新字符串的长度len
    23     int Ans= -1; // 最长回文长度
    24     int P=0;
    25     int MaxLen = 0;
    26     for (int i = 1; i < len; i++)
    27     {
    28         if (i < MaxLen)R[i] = min(R[2 * P - i], MaxLen-i+1);
    29         else R[i] = 1;
    30         while (s[i - R[i]] == s[i + R[i]])R[i]++; //不用判断边界,在Init()中对边界做了处理
    31         if (MaxLen < i + R[i]-1)
    32         {
    33             P = i;
    34             MaxLen = i + R[i]-1;
    35         }
    36         Ans = max(Ans, R[i] - 1);
    37     }
    38     return Ans;
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%s",st);
    44     cout<<Manacher();
    45 }
    46     
     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 #define maxn 51000100
     4 using namespace std;
     5 int n,hw[maxn],ans;
     6 char a[maxn],s[maxn];
     7 void manacher()
     8 {
     9     int maxright=0,mid;
    10     for(int i=1;i<n;i++)
    11     {
    12         if(i<maxright)
    13             hw[i]=min(hw[(mid<<1)-i],hw[mid]+mid-i);
    14         else
    15             hw[i]=1;
    16         for(;s[i+hw[i]]==s[i-hw[i]];++hw[i]);
    17         if(hw[i]+i>maxright)
    18         {
    19             maxright=hw[i]+i;
    20             mid=i;
    21         }
    22     }
    23 }
    24 void change()
    25 {
    26     s[0]=s[1]='#';
    27     for(int i=0;i<n;i++)
    28     {
    29         s[i*2+2]=a[i];
    30         s[i*2+3]='#';
    31     }
    32     n=n*2+2;
    33     s[n]=0;
    34 }
    35 int main()
    36 {
    37     scanf("%s",a);
    38     n=strlen(a);
    39     change();
    40     manacher();
    41     ans=1;
    42     for(int i=0;i<n;i++)
    43         ans=max(ans,hw[i]);
    44    cout<<ans-1;
    45     return 0; 
    46 }
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 阮小二买彩票
    Java实现 蓝桥杯VIP 算法提高 传染病控制
    Java实现 蓝桥杯VIP 算法提高 传染病控制
    Java实现 蓝桥杯VIP 算法提高 传染病控制
    Java实现 蓝桥杯VIP 算法提高 传染病控制
    Java实现 蓝桥杯VIP 算法提高 传染病控制
    Java实现 蓝桥杯VIP 算法提高 企业奖金发放
    Java实现 蓝桥杯VIP 算法提高 企业奖金发放
    让程序后台隐藏运行
    只要你喜欢,并且可以养家糊口,就是好的
  • 原文地址:https://www.cnblogs.com/CXYscxy/p/11344784.html
Copyright © 2011-2022 走看看