http://acm.hdu.edu.cn/showproblem.php?pid=5340
Problem Description
Can we divided a given string S into three nonempty palindromes?
Input
First line contains a single integer T≤20 which
denotes the number of test cases.
For each test case , there is an single line contains a string S which only consist of lowercase English letters.1≤|s|≤20000
Output
For each case, output the "Yes" or "No" in a single line.
Sample Input
2 abc abaadada
Sample Output
Yes No
/** hdu 5340 最长回文子串变形 题目大意:给定一个字符串问是否正好可以分成三个回文子串(不能为空串) 解题思路:如果直接枚举判断时间复杂度为O(n^3)。可以利用Manacher算法求出所有0~i为回文串和j~n-1为回文串的i和j 最后枚举这两个位置利用原本求出的r[i],判断中间的是不是回文串即可。复杂度不会超过O(n^2) */ #include<iostream> #include<cmath> #include<string.h> #include<stdio.h> #include<algorithm> using namespace std; const int maxn=110010; /** * 求最长回文子串O(n) * abaaba * i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 * a[i]: $ # a # b # a # a # b # a # * r[i]: 1 1 2 1 4 1 2 7 2 1 4 1 2 1 * answer=(max(r[i]-1)) */ char a[maxn*2],s[maxn]; int r[maxn*2]; int c1[20011],c2[20011];///0~i满足回文的所有i;j~n-1满足回文的所有j void Manacher(char s[],int n) { int l=0; a[l++]='$'; a[l++]='#'; for(int i=0; i<n; i++) { a[l++]=s[i]; a[l++]='#'; } a[l]=0; int mx=0,id=0; for(int i=0; i<l; i++) { r[i]=mx>i?min(r[2*id-i],mx-i):1; while(a[i+r[i]]==a[i-r[i]])r[i]++; if(i+r[i]>mx) { mx=i+r[i]; id=i; } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",s); int n=strn(s); Manacher(s,n); int l1=0,l2=0; for(int i=1; i<2*n+2; i++) { if(r[i]==i && i!=1) { l1++; c1[l1]=r[i]-1; } if(r[i]==2*n+2-i && i!=2*n+1) { l2++; c2[l2]=r[i]-1; } } int flag=1; for(int i=l1; i>=1&&flag; i--) { for(int j=1; j<=l2&&flag; j++) { int ll=c1[i]*2+2; int rr=2*n+2-(c2[j]*2+2); int tmp=(ll+rr)/2; if(ll>rr) continue; if(r[tmp]-1==0) continue; if(r[tmp]>=(rr-ll+2)/2) { flag=0; } } } if(flag)puts("No"); else puts("Yes"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-13 12:19:42