hiho1032 : 最长回文子串 Manacher算法
2015-06-12 16:45
357 查看
时间限制:1000ms
单点时限:1000ms
内存限制:64MB
小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。
这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”
小Ho奇怪的问道:“什么叫做最长回文子串呢?”
小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”
小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?
小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”
样例输入
样例输出
单点时限: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)。关于Manacher的具体介绍可以参考这篇文章。
http://www.felix021.com/blog/read.php?2040
#include <map> #include <set> #include <list> #include <deque> #include <queue> #include <cmath> #include <stack> #include <string> #include <vector> #include <cctype> #include <cstdio> #include <cstdlib> #include <cstring> #include <utility> #include <iostream> #include <iterator> #include <algorithm> using namespace std; #define REP(i, n) for(int i = 0; i < n; ++i) #define REP1(i, a, n) for(int i = a; i <= n; ++i) #define REPD(i, n) for(int i = n; i >= 0; --i) #define clm(m, a) memset(m, a, sizeof(m)) #define ee 2.71828182845904523536 #define PI 3.14159265358979323846 #define exp 1e-9 #define fi first #define se second typedef long long ll; typedef unsigned long long llu; typedef pair<int, int> pii; const int MAXN = 1e6+5; char s[MAXN]; char Ma[MAXN<<1]; int Mp[MAXN<<1]; void Manacher(char s[], int len) { int l = 0; Ma[l++] = '$'; Ma[l++] = '#'; REP(i, len) { Ma[l++] = s[i]; Ma[l++] = '#'; } Ma[l] = 0; int mx = 0, id = 0; REP(i, l) { Mp[i] = mx > 1 ? min(Mp[2*id-i], mx-i) : 1; while(Ma[i+Mp[i]] == Ma[i-Mp[i]]) Mp[i]++; if(i+Mp[i] > mx) { mx = i+Mp[i]; id = i; } } } int main() { #ifdef LOCAL freopen("in","r",stdin); #endif int cases; scanf("%d", &cases); gets(s); while(cases--) { gets(s); int len = strlen(s); Manacher(s, len); int ans = 0; REP(i, 2*len+2) { ans = max(ans, Mp[i]-1); } printf("%d\n", ans); } return 0; }
相关文章推荐
- android 照片拍照问题
- setContentView(R.layout.activity_main)无法正常引用
- 手动设置Xen Host网络
- 采访100多个开发者带来的7点感悟
- MVC中,加入的一个aspx页面用到AspNetPager控件处理办法
- std::sort引发的core
- zabbix 客户端安装
- 黑马程序员—继承、接口
- HTTPS原理
- Webview的使用
- Android学习笔记 :Android动画 tween,frame,property
- UCI数据集和源代码
- UBUNTU上安装GCC-4.9.2
- 我看Java二十年:它是如何永远改变编程的。
- 如何写makefile
- 读后感10~12
- 关于appserv的安装问题
- 我看Java二十年:它是如何永远改变编程的。
- C#产品研发篇
- quartz入门(一)下载及简单实例