Hihocoder #1032 : 最长回文子串 (Manacher算法)
2016-07-14 23:06
218 查看
#1032 : 最长回文子串
时间限制: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
题解:Manacher算法o(n)求解最长回文子串问题 ,经典!
AC代码:
#include<bits/stdc++.h> using namespace std; char str[2000020],s[2000020]; int p[2000020]; int len,id,mx; void pre() //对字符串进行预处理 { len=strlen(s); str[0]='$'; str[1]='#'; for(int i=0;i<len;i++) { str[i*2+2]=s[i]; str[i*2+3]='#'; } len=len*2+2; str[len]=0; } void Manacher() //算法核心 { mx=0; for(int i=1;i<len;i++) { if(mx>i) p[i]=min(p[2*id-i],mx-i); else p[i]=1; while(str[i+p[i]]==str[i-p[i]]) p[i]++; if(p[i]+i>mx) { mx=p[i]+i; id=i; } } } int main() { int N; scanf("%d",&N); for(int i=1;i<=N;i++) { scanf("%s",s); pre(); Manacher(); printf("%d\n",p[max_element(p,p+len)-p]-1); } return 0; }
相关文章推荐
- RecyclerView的item的点击事件
- Servlet学习笔记(中文乱码处理)
- 【LoadRunner】Http协议下关联的脚本易错点和注意事项
- Java 输入输出流认识(一)
- Android 的输入管理学习计划
- Java虚拟机学习笔记-第二章(上)
- 百度地图在Activity中以最简单的配置获取定位坐标字符串和经纬度
- 365. Water and Jug Problem
- Gson 解析多层嵌套JSON数据
- iOS-Quartz2D画图
- POI导出excel的整个过程
- 剑指offer 22题 【举例让抽象具体化】栈的压入、弹出序列
- mongodb的备份
- 258. Add Digits
- linux环境下的命令
- day_4-acm 水题爆数据
- 一台服务器的黑道生涯之六 保安来了
- UVA 10499 The Land of Justice
- android中获取位置(一)--利用locationManager获取当前经纬度信息
- 社会工程学攻击库(持续更新)