URAL 题目1297. Palindrome(后缀数组+RMQ求最长回文子串)
1297. Palindrome
Memory limit: 64 MB
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).
Unfortunately, he was fired just before his team has finished work on the NPRx8086 design.
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.
the program.
Input
Output
Sample
input | output |
---|---|
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA |
ArozaupalanalapuazorA |
Problem Source: IX Open Collegiate Programming Contest of the High School Pupils (13.03.2004)
Difficulty: 96 space=1&num=1297" target="_blank">Printable version space=1&num=1297">Discussion
(62)
My submissions space=1&num=1297">All submissions (19930)
accepted submissions (6214) Solutions rating (4095)
ac代码
首先肯定是要把原字符的逆序串接到原字符串的后面。然后便是从0~~len扫描这个字符串,如果第i个位置是一个回文的中心。然后求出i个i相应位置的lca的最大值就可以。每次枚举时要分奇偶两种情况考虑。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
using namespace std;
char str[3030];
int sa[3030],Rank[3030],rank2[3030],height[3030],c[3030],*x,*y,s[3030];
int n;
void cmp(int n,int sz)
{
int i;
memset(c,0,sizeof(c));
for(i=0;i<n;i++)
c[x[y[i]]]++;
for(i=1;i<sz;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)
sa[--c[x[y[i]]]]=y[i];
}
void build_sa(int *s,int n,int sz)
{
x=Rank,y=rank2;
int i,j;
for(i=0;i<n;i++)
x[i]=s[i],y[i]=i;
cmp(n,sz);
int len;
for(len=1;len<n;len<<=1)
{
int yid=0;
for(i=n-len;i<n;i++)
{
y[yid++]=i;
}
for(i=0;i<n;i++)
if(sa[i]>=len)
y[yid++]=sa[i]-len;
cmp(n,sz);
swap(x,y);
x[sa[0]]=yid=0;
for(i=1;i<n;i++)
{
if(y[sa[i-1]]==y[sa[i]]&&sa[i-1]+len<n&&sa[i]+len<n&&y[sa[i-1]+len]==y[sa[i]+len])
x[sa[i]]=yid;
else
x[sa[i]]=++yid;
}
sz=yid+1;
if(sz>=n)
break;
}
for(i=0;i<n;i++)
Rank[i]=x[i];
}
void getHeight(int *s,int n)
{
int k=0;
for(int i=0;i<n;i++)
{
if(Rank[i]==0)
continue;
k=max(0,k-1);
int j=sa[Rank[i]-1];
while(s[i+k]==s[j+k])
k++;
height[Rank[i]]=k;
}
}
int minv[3010][20],lg[3030];
void init_lg()
{
int i;
lg[1]=0;
for(i=2;i<2020;i++)
{
lg[i]=lg[i>>1]+1;
}
}
void init_RMQ(int n)
{
int i,j,k;
for(i=1;i<=n;i++)
{
minv[i][0]=height[i];
}
for(j=1;j<=lg[n];j++)
{
for(k=0;k+(1<<j)-1<=n;k++)
{
minv[k][j]=min(minv[k][j-1],minv[k+(1<<(j-1))][j-1]);
}
}
}
int lcp(int l,int r)
{
l=Rank[l];
r=Rank[r];
if(l>r)
swap(l,r);
l++;
int k=lg[r-l+1];
return min(minv[l][k],minv[r-(1<<k)+1][k]);
}
int main()
{
while(scanf("%s",str)!=EOF)
{
int n=0,i;
int len=strlen(str);
for(i=0;i<len;i++)
{
s[n++]=str[i];
}
s[n++]=127;
for(i=len-1;i>=0;i--)
s[n++]=str[i];
s[n]=0;
build_sa(s,n+1,128);
getHeight(s,n);
init_lg();
init_RMQ(n);
int ans=-1,st;
for(i=0;i<len;i++)
{
int temp=lcp(i,n-i-1);
if(temp*2-1>ans)
{
ans=temp*2-1;
st=i-temp+1;
}
temp=lcp(i,n-i);
if(temp*2>ans)
{
ans=temp*2;
st=i-temp;
}
}
// printf("%d %d\n",ans,st);
if(ans==1)
printf("%c\n",str[0]);
else
{
for(i=0;i<ans;i++)
{
printf("%c",str[i+st]);
}
printf("\n");
}
}
}
URAL 题目1297. Palindrome(后缀数组+RMQ求最长回文子串)的更多相关文章
- URAL 1297 后缀数组:求最长回文子串
思路:这题下午搞了然后一直WA,后面就看了Discuss,里面有个数组:ABCDEFDCBA,这个我输出ABCD,所以错了. 然后才知道自己写的后缀数组对这个回文子串有bug,然后就不知道怎么改了. ...
- hdu 3068 最长回文(manachar求最长回文子串)
题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...
- Manacher模板( 线性求最长回文子串 )
模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...
- Manacher算法 O(n) 求最长回文子串
转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
- manacher算法求最长回文子串
一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...
随机推荐
- C# 转换图形为PCX 格式
2010-5-27 PCX RLE压缩图形的行对齐比.NET多了一位.已经修正了. 2009 -7-25 C# 转换图形为PCX 格式 增加了对1位色的PCX的读取 2009-6 -12 RLE数据压 ...
- 游戏编程之Unity常用脚本类的继承关系
前言学习Unity开发引擎的初学者会接触大量的脚本类,而这些类之间的关系往往容易被忽略.本文对Unity引擎开发中的一些常用类及其关系进行了简单的归纳总结. 博文首发地址:http://tieba.b ...
- Oracle数据库--解决单张表中数据量巨大(大数据、数据量上百万级别,后查询,更新数据等耗时剧增)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/QQ578473688/article/details/54561397 思路1:采用备份表 备份表中 ...
- ProGuard使用简介
我们做java开发的一般都会遇到如何保护我们开发的代码问题.java语言由于是基于jvm上面,所以反编译class 文件很很容易.假如我们做了一个web程序,并把这个web程序发布给客户.实际上,客户 ...
- Additive属性动画
Additive属性动画 参考 http://ronnqvi.st/multiple-animations/ 效果 源码 https://github.com/YouXianMing/Animatio ...
- 修改Eclipse/MyEclipse项目的默认编码
应该是中文操作系统的原因,eclipse默认的新项目的编码是GBK,出于对编码支持的考虑,项目组中最好统一要求是UTF-8编码进行开发. 修改eclipse的配置,可以使得eclipse的新建项目的默 ...
- Android之判断当前网络状态
/** * 检测网络是否可用 * @return */ public boolean isNetworkConnected() { ConnectivityManager cm = (Connecti ...
- DAHON 美国大行
DAHON美国大行1982年创立于美国加州,多年来一直率先推动环保的代步工具——折叠自行车.创新是大行的生命,从韩氏兄弟发明了全世界第一辆小到能够放进火车座椅底下的折叠自行车起,大行就开启了不断向前的 ...
- hdu 4548 美素数 超级大水题
美素数 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submis ...
- freetds简介、安装、配置及使用介绍
什么是FreeTDS 简单的说FreeTDS是一个程序库,可以实现在Linux系统下访问微软的SQL数据库! FreeTDS 是一个开源(如果你喜欢可以称为自由)的程序库,是TDS(表列数据流 )协议 ...