zoukankan      html  css  js  c++  java
  • hdu 3068 最长回文【manacher】(模板题)

    <题目链接>

                                           最长回文

    Problem Description
    给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
    回文就是正反读都是一样的字符串,如aba, abba等
     
    Input
    输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
    两组case之间由空行隔开(该空行不用处理)
    字符串长度len <= 110000
     
    Output
    每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
     
    Sample Input
    aaaa
    abab
     
    Sample Output
    4
    3
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 2e5+5;
    int len[N];
    char str[N],s[N];
    
    void init(){    //得到处理后的新字符串
        str[0]='@';
        int i;for(i=0;s[i]!=0;i++){
            str[2*i+1]='#';
            str[2*i+2]=s[i];
        }
        str[2*i+1]='#';
        str[2*i+2]=0;
    }
    int manacher(){
        int id=0,mx=0;      //id为能当前能够到达字符串最右端的回文串的中心位置
        for(int i=1;str[i];i++){
            len[i]=mx>i?min(len[2*id-i],mx-i):1;    //  2*id-i,指的是i关于id 对称得到的坐标,因为前面已经算过了mx前的每个点的回文串,所以,如果这个i点在mx范围内,就将len[i]初始化为前面算过的数值
            while(str[i+len[i]]==str[i-len[i]])len[i]++;
            if(i+len[i]>mx)   //mx为前i个回文子串的右端点所能到达的最大距离,即前面已经算过的最大回文区域
                mx=i+len[i],id=i;
        }
        int ans=0;
        for(int i=1;str[i];i++)ans=max(ans,len[i]);
        return ans-1;    //回文串长度为len[i]-1,这个可以自己画图理解,因为s[]数组是在原串的基础上插入了 '#'
    }
    int main(){
        while(~scanf("%s",s)){
            init();
            printf("%d
    ",manacher());
        }
    }

      

  • 相关阅读:
    c# 自定义位数生成激活码
    接口interface和抽象类型abstract
    winform自动升级方案
    泛型介绍
    泛型约束形式
    登录状态保持Session/Cookie
    EFCore 2.0引用标量函数
    .net生成条形码
    通用手机号、身份证号等隐藏显示方法
    .net core api Post请求
  • 原文地址:https://www.cnblogs.com/00isok/p/9419714.html
Copyright © 2011-2022 走看看