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. Xshell小技巧

    1. 鼠标右键粘贴 工具->选项->鼠标->向右按钮->(paste the clipboard contents.) 2. 选定文本自动复制到剪贴板 工具->选项-&g ...

  2. Scala 深入浅出实战经典 第43讲:主要介绍类型变量bound

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  3. VS2013 修改TFS的本地映射路径

    在源代码管理器里面 找到你的本地工作区 然后点击编辑按钮 修改本地目录

  4. 直接使用提交过来的类来更新字段EntityState.Modified并过滤null值的方法

    public T Update<T>(T entity) where T : ModelBase { var set = this.Set<T>(); set.Attach(e ...

  5. 在ps中画两个同心圆并且把两个同心圆进行任意角度切割

    在工作中遇到要在ps中画如图两个同心圆,并且进行6等分.查找资料加自己摸索,可以通过以下方式实现: 1.新建一画布.并用通过标尺画出两条水平和垂直参考线,选择椭圆工具,并在选项设置中选择圆和从中心两个 ...

  6. Android Studio 中关于NDK编译及jni header生成的问题

    之前由于工作原因使用grails这个基于groovy的框架做项目,对groovy感觉很好. 基于groovy的gradle构建系统对我而言自然也是好的没得说. Android Studio 正式版出来 ...

  7. Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI

    WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在 ...

  8. 阿里云 Redis 服务遇到的问题

    ERR unknown command eval 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: St ...

  9. 日暮·第一章·决斗

    日暮 第一章 决斗   泉州府,位于帝国的东南沿海,在数百年前,这里已是帝国最大的通商口岸之一,其一城之繁荣喧哗足以与异邦小国的都城相媲美,无数的人曾经来到这里,追逐财富,梦想,女人以及所有他们认为可 ...

  10. C用函数指针模拟重载 C++重载

    C中为什么不支持重载,即同一作用域内不允许出现同名函数? 我们都知道重载是c++面向对象的特性.c语言中是不存在的.所谓重载简单来说就是一个函数名可以实现不同的功能,要么输入参数不同或者参数个数不同, ...