Three Palindromes
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1273 Accepted Submission(s): 424
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
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给定一字符串 ,判定是否可以分为连续的三部分,每一部分是个回文串Manacher算法求出各点距右端最大的回文长度,在第一和第三部分满足回文的条件下,看第二部分是否满足#include <cstdio> #include <algorithm> #include <stdlib.h> #include <cstring> #include <iostream> #include <cmath> #define maxn 20010 using namespace std; char a[maxn]; char tmp[maxn*2]; int Len[maxn*2]; int one[maxn*2]; int three[maxn*2]; int init(char s[]) { tmp[0]='$'; int len = strlen(s); for(int i=1; i<=2*len; i+=2) { tmp[i] = '#'; tmp[i+1] = s[i/2]; } tmp[2*len+1] ='#'; tmp[2*len+2] = '@'; return 2*len+1; } void Manacher(char s[],int len) { int mx=0; int po=0; for( int i=1; i<=len; i++) { if(mx > i) Len[i] = min(mx-i , Len[2*po-i]); else Len[i] = 1; while( s[i-Len[i]]== s[i+Len[i]] ) { Len[i]++; } if(Len[i]+i>mx) { po=i; mx=Len[i]+i; } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",a); int len = init(a); Manacher(tmp,len); int k1=0; int k2=0; for(int i=2; i<len; i++) { if(Len[i]==i) one[k1++]=Len[i]; if(len==Len[i]+i-1) three[k2++]=Len[i]; } bool flag=false; for(int i=0;i<k1;i++) { for(int j=0;j<k2;j++) { int t1 = 2*one[i]; //第二段起点 int t2 = len-2*three[j]+1; //第二段终点 if(t1>t2) continue; int r = (t1+t2)/2; if(Len[r]==1) continue; if(Len[r]*2-1 >= t2-t1+1) //第二段的回文长度>=除去第一段和第三段的长度 { flag=true; break; } } if(flag) break; } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }