hihocoder 1032 最长回文子串 (Manacher算法 详解+模板)

2024-03-20 13:38

本文主要是介绍hihocoder 1032 最长回文子串 (Manacher算法 详解+模板),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

时间限制:1000ms
单点时限:1000ms
内存限制:64MB

描述

   小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

   这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

   小Ho奇怪的问道:“什么叫做最长回文子串呢?”

   小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

   小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

   小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

提示一提示二提示三提示四
样例输入
3
abababa
aaaabaa
acacdas
样例输出
7
5
3 

题目链接:http://hihocoder.com/problemset/problem/1032


题目分析:Manacher算法可以在O(n)的时间复杂度内解决最长回文子串问题,下面介绍一下这个算法

首先对于一个任意长度的字符串,通过插入无关字符法均可以将其变成奇数长度,如aba => #a#b#a#,abba => #a#b#b#a#,为了解决边界问题可以直接在最前面再加上一个无关字符,令cur为当前能延伸到最右端的回文子串的中心位置,p[cur]表示当前能延伸到最右端的回文子串的回文半径,而p[cur] + cur就是当前能延伸到的最右端,当前位置i如果在其范围之外,即p[cur] + cur < i则p[i] = 1(自己另起一段回文子串),如果p[cur] + cur >= i,也就是当前位置在其范围内,则此时p[i] = min(p[cur * 2 - i],p[cur] + cur - i),这里分两种情况,1) p[cur * 2 - i] > p[cur] + cur - i,也就是说以i当前的对称点为中心的回文子串范围在当前cur为中心的回文子串的最左端的左边,则这时p[i] = p[cur] + cur - i;p[cur] + cur - i指的是当前cur为中心的回文串的最右端到当前点i的距离,2) p[cur * 2 - i] <= p[cur] + cur - i,情况类似上面,画图很容易看出来,算出p[i],则以当前的i为中心向两端扩展,若扩展出来的最右端超过原来的最右端则更新cur

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e6 + 5;
char s[MAX << 1];
int p[MAX << 1];int Manacher()
{int len = strlen(s);for(int i = len; i >= 0; i--){s[(i << 1) + 2] = s[i];s[(i << 1) + 1] = '#';}s[0] = '*';int cur = 0, ans = 0;for(int i = 2; i < 2 * len + 1; i++){if(p[cur] + cur >= i)p[i] = min(p[(cur << 1) - i], p[cur] + cur - i);elsep[i] = 1;while(s[i - p[i]] == s[i + p[i]])p[i] ++;if(p[cur] + cur < i + p[i])cur = i;ans = max(ans, p[i]);}return ans - 1;
}int main()
{int n;scanf("%d", &n);while(n --){scanf("%s", s);printf("%d\n", Manacher());}
}


这篇关于hihocoder 1032 最长回文子串 (Manacher算法 详解+模板)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829617

相关文章

C语言中的浮点数存储详解

《C语言中的浮点数存储详解》:本文主要介绍C语言中的浮点数存储详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、首先明确一个概念2、接下来,讲解C语言中浮点型数存储的规则2.1、可以将上述公式分为两部分来看2.2、问:十进制小数0.5该如何存储?2.3 浮点

大数据spark3.5安装部署之local模式详解

《大数据spark3.5安装部署之local模式详解》本文介绍了如何在本地模式下安装和配置Spark,并展示了如何使用SparkShell进行基本的数据处理操作,同时,还介绍了如何通过Spark-su... 目录下载上传解压配置jdk解压配置环境变量启动查看交互操作命令行提交应用spark,一个数据处理框架

MySQL中COALESCE函数示例详解

《MySQL中COALESCE函数示例详解》COALESCE是一个功能强大且常用的SQL函数,主要用来处理NULL值和实现灵活的值选择策略,能够使查询逻辑更清晰、简洁,:本文主要介绍MySQL中C... 目录语法示例1. 替换 NULL 值2. 用于字段默认值3. 多列优先级4. 结合聚合函数注意事项总结C

Java实现数据库图片上传功能详解

《Java实现数据库图片上传功能详解》这篇文章主要为大家详细介绍了如何使用Java实现数据库图片上传功能,包含从数据库拿图片传递前端渲染,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、数据库搭建&nbsChina编程p; 3、后端实现将图片存储进数据库4、后端实现从数据库取出图片给前端5、前端拿到

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID

MySql中的数据库连接池详解

《MySql中的数据库连接池详解》:本文主要介绍MySql中的数据库连接池方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql数据库连接池1、概念2、为什么会出现数据库连接池3、原理4、数据库连接池的提供商5、DataSource数据源6、DBCP7、C

Spring-AOP-ProceedingJoinPoint的使用详解

《Spring-AOP-ProceedingJoinPoint的使用详解》:本文主要介绍Spring-AOP-ProceedingJoinPoint的使用方式,具有很好的参考价值,希望对大家有所帮... 目录ProceedingJoinPoijsnt简介获取环绕通知方法的相关信息1.proceed()2.g

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

一文详解kafka开启kerberos认证的完整步骤

《一文详解kafka开启kerberos认证的完整步骤》这篇文章主要为大家详细介绍了kafka开启kerberos认证的完整步骤,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、kerberos安装部署二、准备机器三、Kerberos Server 安装1、配置krb5.con

Python使用DeepSeek进行联网搜索功能详解

《Python使用DeepSeek进行联网搜索功能详解》Python作为一种非常流行的编程语言,结合DeepSeek这一高性能的深度学习工具包,可以方便地处理各种深度学习任务,本文将介绍一下如何使用P... 目录一、环境准备与依赖安装二、DeepSeek简介三、联网搜索与数据集准备四、实践示例:图像分类1.