【HDOJ 5371】 Hotaru's problem
来源:互联网 发布:邮箱都有哪些域名 编辑:程序博客网 时间:2024/05/20 06:29
【HDOJ 5371】 Hotaru’s problem
Manacher算法+穷举/set
Manacher算法一好文:http://blog.csdn.net/yzl_rex/article/details/7908259
套一个Manacher算出回文半径数组p之后 有两种方法
穷举法:
枚举-1的点(根据题意只必为偶数回文) 找在该点回文半径内与其相隔最远 并且回文半径等于他俩距离(即两点为中心的回文串相同) 的点 记录找到时的距离 不断枚举找最大值即为最大回文串长 串长/2*3即为答案
set法:
记录-1的位置 根据每个-1对应的回文半径排序 从大到小枚举加入set 每加入一个位置i后 查找大于i-p[i]的第一个数(lower_bound) 和小于等于i+p[i]的第一个数(–upper_bound) 该位置与这两个位置的距离即为各自组成的回文串长度的二分之一 找到最大的*3即为答案
代码如下:
//穷举#include <iostream>#include <cstdio>#include <cstdlib>using namespace std;int nwm[200002];int p[200002];void Manacher(int n)//马拉车模板{ nwm[0] = -2; int i; for(i = 0; i < n; i++) { nwm[i*2+1] = -1; scanf("%d",&nwm[i*2+2]); } nwm[n*2+1] = -1; nwm[n*2+2] = -3; int maxid = 0,id; n = n*2+2; for(i = 2; i < n; ++i) { if(maxid > i) p[i] = min(p[id*2-i],maxid-i); else p[i] = 1; while(nwm[i+p[i]] == nwm[i-p[i]]) p[i]++; if(p[i]+i > maxid) { maxid = p[i]+i; id = i; } }}int main(){ int t,n,z = 0,i,mm,x; scanf("%d",&t); while(t--) { mm = 0; scanf("%d",&n); Manacher(n); for(i = 3; i +4< n*2+2; i+=2)//枚举-1 { if(p[i]-1 > mm) { x = p[i]-1;//记录-1为中心的最大回文串长 while(x > mm && p[i+x] < x)//枚举找满足题意的第二回文中心 x--; mm = max(mm,x); } } printf("Case #%d: %d\n",++z,mm/2*3); } return 0;}
//set方法#include <iostream>#include <cstdio>#include <cstdlib>#include <set>#include <algorithm>using namespace std;int nwm[200002];int p[200002];int id[200002],tp;set <int> s;void Manacher(int n){ nwm[0] = -2; int i; for(i = 0; i < n; i++) { nwm[i*2+1] = -1; id[tp++] = i*2+1;//将-1位置记录 scanf("%d",&nwm[i*2+2]); } nwm[n*2+1] = -1; nwm[n*2+2] = -3; int maxid = 0,id; n = n*2+2; for(i = 2; i < n; ++i) { if(maxid > i) p[i] = min(p[id*2-i],maxid-i); else p[i] = 1; while(nwm[i+p[i]] == nwm[i-p[i]]) p[i]++; if(p[i]+i > maxid) { maxid = p[i]+i; id = i; } }}bool cmp(int a,int b)//按-1对应回文距离由大到小排序{ return p[a] > p[b];}int main(){ int t,n,z = 0,i,mm,x,l,r; scanf("%d",&t); while(t--) { s.clear(); tp = 0; mm = 0; scanf("%d",&n); Manacher(n); sort(id,id+tp,cmp); for(i = 0; i < tp; ++i)//回文距离从大到小枚举位置 { s.insert(id[i]); l = *s.lower_bound(id[i]-p[id[i]]);//找左边第一个>=id[i]-p[id[i]]的位置 r = *(--s.upper_bound(id[i]+p[id[i]]));//找右边第一个<=id[i]+p[id[i]]的位置 mm = max(mm,max(id[i]-l,r-id[i])); } printf("Case #%d: %d\n",++z,mm/2*3); } return 0;}
0 0
- 【HDOJ 5371】 Hotaru's problem
- HDOJ-5371 Hotaru's problem(Manacher)
- HDOJ 5371 Hotaru's problem manacher+优先队列+二分
- HDU 5371 Hotaru's problem
- HDU 5371 Hotaru's problem
- HDU 5371 Hotaru's problem
- HDU 5371 Hotaru's problem
- hdu 5371 Hotaru's problem
- HDU 5371 Hotaru's problem
- HDU 5371 - Hotaru's problem(Manacher算法)
- hdu 5371 Hotaru's problem (Manacher算法)
- hdu 5371 Hotaru's problem(manachar)
- hdu 5371 Hotaru's problem【manacher】
- hdu 5371 Hotaru's problem (Manacher算法)
- HDU 5371 Hotaru's problem Manacher+Set
- HDU 5371 Hotaru's problem(Manacher)
- [HDU 5371]Hotaru's problem:Manacher
- 【manacher】hud 5371 Hotaru's problem
- Segment Game (hdu 5372 树状数组+离散化)
- Java基础总结之各个模块重要知识点
- 共享内存
- iOS推送小结
- 不敢死队问题
- 【HDOJ 5371】 Hotaru's problem
- Python代码运行助手
- 8 个不得不说的 MySQL 陷阱
- Objective-C——判断对象等同性
- xilinx bit流生成错误
- HDU 4200
- 反射的一个应用场景
- Android动画详解
- trie hdu1075