hdu 5340 Three Palindromes
2015-08-02 19:57
302 查看
给一个串,问是否能把它拆为三个回文串。
用Manachar计算以每个字符为中心的最长回文串长度,然后枚举头尾,判断中心是否为回文串。
理解了一下manachar,它从左往右扫,记录每个位置为中心的最长回文串长度,维护了当前回文串能到达的最右边的位置和回文串长度、中心。根据这些信息以及对称性,就可以推知下一个位置回文长度至少是多少。虽然有两重循环,但内循环只会执行O(n)次,因为当前回文串能到达的最右边是单调递增的。
官方题解给的二进制压位优化没有弄明白,求大神解释。。不压位写好点也是能过的。
然后一个学弟把压位看明白了,其实想明白就简单了。。就是把32个0或1的位压到一个int里,一次性比较32位。。优化常数。。就不实现了。
用Manachar计算以每个字符为中心的最长回文串长度,然后枚举头尾,判断中心是否为回文串。
理解了一下manachar,它从左往右扫,记录每个位置为中心的最长回文串长度,维护了当前回文串能到达的最右边的位置和回文串长度、中心。根据这些信息以及对称性,就可以推知下一个位置回文长度至少是多少。虽然有两重循环,但内循环只会执行O(n)次,因为当前回文串能到达的最右边是单调递增的。
官方题解给的二进制压位优化没有弄明白,求大神解释。。不压位写好点也是能过的。
然后一个学弟把压位看明白了,其实想明白就简单了。。就是把32个0或1的位压到一个int里,一次性比较32位。。优化常数。。就不实现了。
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <algorithm> #include <stdlib.h> #include <math.h> #include <stack> using namespace std; const int MAX = 20010; int len, p[2*MAX]; char str[2*MAX], newstr[2*MAX]; void change(){ int i; newstr[0] = '@'; newstr[1] = '#'; for (i = 0; i < len; i++){ newstr[2*i + 2] = str[i]; newstr[2*i + 3] = '#'; } newstr[2*len + 2] = '\0'; return ; } void Manacher(){ int i, j, id, maxid = 0, ans = 1; len = 2 * len + 2; for (i = 0; i < len; i++){ if (maxid > i){ p[i] = min(p[2*id - i], maxid - i); } else{ p[i] = 1; } while (newstr[i+p[i]] == newstr[i-p[i]]) p[i]++; if (p[i] + i > maxid){ maxid = p[i] + i; id = i; } if (ans < p[i]) ans = p[i]; } return ; } int head[MAX]; int tail[MAX]; int main(){ int t; cin>>t; while (t--){ scanf("%s", &str); len = strlen(str); change(); Manacher(); int headCnt=0; int tailCnt=0; for(int i=2;i<=len-2;i++){ if(p[i]==i){ head[headCnt++]=i; } if(p[i]==len-i){ tail[tailCnt++]=i; } } bool ok=0; for(int i=0;i<headCnt;i++){ for(int j=0;j<tailCnt;j++){ int l=head[i]+p[head[i]] ; int r=tail[j]-p[tail[j]] ; if(l>r)continue; int mid = (head[i]+p[head[i]] + tail[j]-p[tail[j]])>>1; if(l==r&&newstr[mid]=='#')continue; if(p[head[i]]*2-1+p[tail[j]]*2-1+p[mid]*2-1>=len+1){ ok=1;break; } } if(ok)break; } if(ok){ cout<<"Yes"<<endl; }else{ cout<<"No"<<endl; } } return 0; }
相关文章推荐
- 有向图的欧拉回路及欧拉道路
- java中的I/O流
- Nutch2.2.1 开发环境搭建
- javascript设计模式之Mediator(中介者)模式
- WRL 类库项目模板
- BFS POJ 3126 Prime Path
- SSH学习九 依赖注入及加载Spring配置文件的方法
- 20150802-泛型
- 【转】CAD2012打开自动关闭解决方法
- How to write a good tech blog
- C语言-递归算法以及经典递归(Hanoi)
- 字符串拷贝操作
- Save the Trees
- poj 3662 二分+最短路
- 输入一行字符串,找出其中的相同且长度最长的字符串
- java中怎样在界面中显示图片?
- 使用js编写一个计算器
- NGUI-实例化问题
- Javascript-基础知识(4)
- Quotient Polynomial