hdu5371回文串应用
2016-04-20 20:27
381 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5371
题意,给出一个串,求最长的子串满足:可以分为等长三段,第一段和第三段相同,第一段和第二段构成回文
直接枚举。
一开始数组开了80010一直tle。。
题意,给出一个串,求最长的子串满足:可以分为等长三段,第一段和第三段相同,第一段和第二段构成回文
直接枚举。
一开始数组开了80010一直tle。。
#include <stdio.h> #include <string.h> #include <iostream> #include 26lt;algorithm> using namespace std; const int maxn=100010; int str[maxn],tmp[maxn<<1]; int len1[maxn<<1]; int init(int *st,int n) { int len=n; tmp[0]=-2; for(int i=1;i<=2*len;i+=2) { tmp[i]=-1; tmp[i+1]=st[i/2]; } tmp[2*len+1]=-1; tmp[2*len+2]=-2; tmp[2*len+3]=-3; return 2*len+1; } int manacher(int *st,int len) { int p=0,ans=0,po=0; for(int i=1;i<=len;i++) { if(p>i) len1[i]=min(p-i,len1[2*po-i]); else len1[i]=1; while(st[i-len1[i]]==st[i+len1[i]]) len1[i]++; if(len1[i]+i>p) { p=len1[i]+i; po=i; } ans=max(ans,len1[i]); } return ans-1; } int main() { int T,n,cnt=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&str[i]); int len2=init(str,n); int max1=manacher(tmp,len2); int ans=0; for(int i=1;i<=n*2+1;i+=2) { for(int j=i+len1[i]-1;j-i>ans;j-=2)//这里不要忘了减一 { if(j-i+1<=len1[j]) { ans=max(ans,j-i); break; } } } printf("Case #%d: %d\n",cnt++,ans/2*3); } return 0; }
相关文章推荐
- 复习数学之中国剩余定理和欧拉定理和扩展欧几里德
- Adapter数据变化改变现有View的实现原理及案例
- android基础---->发送和接收短信
- 一种简单的登录加密方案
- 进程间通信-信号量详解及编程实例
- java--web.xml中url-pattern的映射规则
- C++中lower_bound函数和upper_bound函数 以及 sort(参数)
- hdu 4638 Group(莫队算法)
- UVa1592_数据库
- 【NOIP2015模拟11.3】备用钥匙
- Ubuntu init启动流程分析
- 第一次冲刺阶段(三)
- HDU 1166 敌兵布阵
- 站立会议02(第一期)
- Android studio的genymotion的安装
- 卿学姐与公主(线段树区间求最大值)
- 112. Path Sum
- 最小生成树之Prim算法---POJ1258---Agri-Net
- 加域的时候遇到的一点问题
- Linux常用快捷键