1297. Palindrome

Time Limit: 1.0 second
Memory Limit: 16 MB
The “U.S. Robots” HQ has just received a rather alarming anonymous letter. It states that the agent from the competing «Robots Unlimited» has infiltrated into “U.S. Robotics”. «U.S. Robots» security service would have already started an undercover operation to establish the agent’s identity, but, fortunately, the letter describes communication channel the agent uses. He will publish articles containing stolen data to the “Solaris” almanac. Obviously, he will obfuscate the data, so “Robots Unlimited” will have to use a special descrambler (“Robots Unlimited” part number NPRx8086, specifications are kept secret).
Having read the letter, the “U.S. Robots” president recalled having hired the “Robots Unlimited” ex-employee John Pupkin. President knows he can trust John, because John is still angry at being mistreated by “Robots Unlimited”. Unfortunately, he was fired just before his team has finished work on the NPRx8086 design.
So, the president has assigned the task of agent’s message interception to John. At first, John felt rather embarrassed, because revealing the hidden message isn’t any easier than finding a needle in a haystack. However, after he struggled the problem for a while, he remembered that the design of NPRx8086 was still incomplete. “Robots Unlimited” fired John when he was working on a specific module, the text direction detector. Nobody else could finish that module, so the descrambler will choose the text scanning direction at random. To ensure the correct descrambling of the message by NPRx8086, agent must encode the information in such a way that the resulting secret message reads the same both forwards and backwards.
In addition, it is reasonable to assume that the agent will be sending a very long message, so John has simply to find the longest message satisfying the mentioned property.
Your task is to help John Pupkin by writing a program to find the secret message in the text of a given article. As NPRx8086 ignores white spaces and punctuation marks, John will remove them from the text before feeding it into the program.

Input

The input consists of a single line, which contains a string of Latin alphabet letters (no other characters will appear in the string). String length will not exceed 1000 characters.

Output

The longest substring with mentioned property. If there are several such strings you should output the first of them.

Sample

input
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA
output
ArozaupalanalapuazorA 
 

Mean:

给你一个字符串,让你输出字符串的最长回文子串。

analyse:

求最长回文串有很多方法,最经典的莫过于Manacher算法,时间复杂度O(n)。

这里就主要介绍一下用后缀数组的方法。

用后缀数组怎么求回文串呢?

原理和上一篇求最长公共子序列一样,我们把s1反转后接到s1后面得到S串,那么s1的最长回文串必定存在于S中,我们只需要求一下S的height数组,然后寻找来自于不同的两个串的height[i]的最大值,然后记录一下开始位置和长度,最后输出即可。

Time complexity:O(nlogn)

Source code:

Suffix Arrays:

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-05-09-21.22
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define  LL long long
#define  ULL unsigned long long
using namespace std;
const int MAXN=;
//以下为倍增算法求后缀数组
int wa[MAXN],wb[MAXN],wv[MAXN],Ws[MAXN];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}
/**< 传入参数:str,sa,len+1,ASCII_MAX+1 */
void da(const char *r,int *sa,int n,int m)
{
     int i,j,p,*x=wa,*y=wb,*t;
     for(i=; i<m; i++) Ws[i]=;
     for(i=; i<n; i++) Ws[x[i]=r[i]]++;
     for(i=; i<m; i++) Ws[i]+=Ws[i-];
     for(i=n-; i>=; i--) sa[--Ws[x[i]]]=i;
     for(j=,p=; p<n; j*=,m=p)
     {
           for(p=,i=n-j; i<n; i++) y[p++]=i;
           for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
           for(i=; i<n; i++) wv[i]=x[y[i]];
           for(i=; i<m; i++) Ws[i]=;
           for(i=; i<n; i++) Ws[wv[i]]++;
           for(i=; i<m; i++) Ws[i]+=Ws[i-];
           for(i=n-; i>=; i--) sa[--Ws[wv[i]]]=y[i];
           for(t=x,x=y,y=t,p=,x[sa[]]=,i=; i<n; i++)
                 x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
     }
     return;
}
int sa[MAXN],Rank[MAXN],height[MAXN];
/**< str,sa,len */
void calheight(const char *r,int *sa,int n)
{
     int i,j,k=;
     for(i=; i<=n; i++) Rank[sa[i]]=i;
     for(i=; i<n; height[Rank[i++]]=k)
           for(k?k--:,j=sa[Rank[i]-]; r[i+k]==r[j+k]; k++);
     // Unified
     for(int i=n;i>=;--i) ++sa[i],Rank[i]=Rank[i-];
}

char s1[MAXN],s2[MAXN];
int main()
{
     while(~scanf("%s",s1))
     {
           int l1=strlen(s1);
           strcat(s1,"{");
           strcpy(s2,s1);
           for(int i=;i<l1;++i) s1[i+l1+]=s2[l1-i-];
           int len=strlen(s1);
           da(s1,sa,len+,);
           calheight(s1,sa,len);
           int sta=,maxLen=,l,r;
           for(int i=;i<=len;++i)
           {
                 l=min(sa[i]-,sa[i-]-);
                 r=max(sa[i]-,sa[i-]-);
                 if((l<l1&&r>l1) && (len-r==l+height[i]))
                 {
                       if(height[i]>maxLen)
                             maxLen=height[i],sta=l;
                       else if(height[i]==maxLen)
                             sta=min(sta,l);
                 }
           }
           for(int i=sta,j=;j<maxLen;++i,++j)
                printf("%c",s1[i]);
           puts("");
     }
     return ;
}

 Manacher:

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-09-12-15.41
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define max(a,b) (a>b?a:b)
using namespace std;
typedef long long(LL);
typedef unsigned long long(ULL);
const double eps(1e-8);

/** O(n)内求出所有回文串
*原串 :abaaba
*Ma串 :.,a,b,a,a,b,a,
*Mp[i]:Ma串中,以字符Ma[i]为中心的最长回文子串的半径长度(包括Ma[i],也就是把回文串对折后的长度).
****经过对原串扩展处理后,将奇数串的情况也合并到了偶数的情况(不需要考虑奇数串)
*/
const int MAXN=;
char Ma[MAXN*],s[MAXN];
int Mp[MAXN*],Mplen;
void Manacher(char s[],int len)
{
     int le=;
     Ma[le++]='.';
     Ma[le++]=',';
     for(int i=;i<len;++i)
     {
           Ma[le++]=s[i];
           Ma[le++]=',';
     }
     Mplen=le;
     Ma[le]=;
     int pnow=,pid=;
     for(int i=;i<le;++i)
     {
           if(pnow>i)
                 Mp[i]=min(Mp[*pid-i],pnow-i);
           else
                 Mp[i]=;
           for(;Ma[i-Mp[i]]==Ma[i+Mp[i]];++Mp[i]);
           if(i+Mp[i]>pnow)
           {
                 pnow=i+Mp[i];
                 pid=i;
           }
     }
}

int main()
{
     ios_base::sync_with_stdio(false);
     cin.tie();
     while(~scanf("%s",s))
     {
           Manacher(s,strlen(s));
           int maxLen=,idx=;
           for(int i=;i<Mplen;++i)
           {
                 if(Mp[i]>maxLen)
                       maxLen=Mp[i],idx=i;
           }
           for(int i=(idx-maxLen+)/,j=;j<maxLen-;++i,++j)
                 printf("%c",s[i]);
           puts("");
//            cout<<maxLen-1<<endl;
     }
     return ;
}

后缀数组 - 求最长回文子串 + 模板题 --- ural 1297的更多相关文章

  1. hdu 3068 最长回文(manachar求最长回文子串)

    题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...

  2. PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  3. Manacher模板( 线性求最长回文子串 )

    模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...

  4. 求最长回文子串 - leetcode 5. Longest Palindromic Substring

    写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...

  5. Manacher算法 O(n) 求最长回文子串

    转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...

  6. Manacher算法——求最长回文子串

    首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...

  7. manacher算法求最长回文子串

    一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...

  8. 求最长回文子串,O(n)复杂度

    最长回文子串问题-Manacher算法 最长回文串问题是一个经典的算法题. 0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 假设一个字符串正着读和反着读是一样的,那它就是回 ...

  9. manacherO(n)求最长回文子串 hihocoder1032

    原文地址:https://segmentfault.com/a/1190000003914228   http://blog.csdn.net/synapse7/article/details/189 ...

随机推荐

  1. .Net规则引擎介绍 - REngine

    规则引擎 规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策.接受数据输入,解释业务规则,并根据业务规则做出业务决策 ...

  2. 将Sql Server迁移到Always on集群 - 账号的同步

    Always on环境的建立,网上资料很多,主要是windows集群的建立以及Sql Server Always on的建立,略 容易忽略的是Sql server账号同步问题(Always on能实现 ...

  3. HttpURLConnection GET/POST写法

    现在虽然HttpClient很好使,但也有人在用最原生的HttpURLConnection, 记录一下,备忘之. public class HttpUrlConnect { //get请求 publi ...

  4. Living one day at a time (update for a long time)

    1, http://acm.hdu.edu.cn/showproblem.php?pid=1228 2014-04-14  10:39:52 分析:字符串处理题... #include<iost ...

  5. Delphi 中 动态创建的Panel无法改变颜色的解决办法

    刚开始代码如下: procedure TForm1.Button1Click(Sender: TObject); var Panel: TPanel; begin Panel := TPanel.Cr ...

  6. 【Xamarin报错】 COMPILETODALVIK : UNEXPECTED TOP-LEVEL error java.lang.OutOfMemoryError: Java heap space

    Xamarin Android 编译报错: COMPILETODALVIK : UNEXPECTED TOP-LEVEL error java.lang.OutOfMemoryError: Java ...

  7. encfs创建时fuse: failed to exec fusermount: Permission denied错误解决

    今天用encfs创建加密文件夹时碰到提示错误fuse: failed to exec fusermount: Permission denied fuse failed. Common problem ...

  8. Oracle数据库入门——初级系列教程

  9. C# 类型基础——你可能忽略的技术细节

    引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone 其实也就是对象复制.复制又分为了浅度 ...

  10. python 字符串分割

    字符串分割,可以用split,rsplit方法,通过相应的规则来切割成生成列表对象 info = 'name:haha,age:20$name:python,age:30$name:fef,age:5 ...