Test Instructions : give you a string to ask can be split into three palindrome string? Output Yes, otherwise output No.
Knowledge Supplement:
Longest palindrome substring algorithm (manacher algorithm):
The linear time complexity algorithm for the longest palindrome substring is solved by the method of central expansion, which avoids the repetition computation greatly. The implementation is as follows:
- To avoid a discussion of the odd even number of strings, first preprocess the string as follows:
规则为在字符间和两边插入‘#‘字符,为了避免越界处理,最两边插入‘^‘和‘$‘字符。原本字符串为:asd预处理后为:^#a#s#d#$
- Then implement part:
设置两个变量:c 和 r,表示当前最长回文字符串的中心和边界。数组p[max],p[i]表示以i为中心的回文字符串的长度
after the string from left to right processing, there is a longer palindrome string to update C and R. This is the following conclusion:对于以i为中心的字符串,如果i < r,那么就有:p[i] >= min(p[2 * c - i], r - i)。然后再进行扩展。即可
根据实现后得到的p数组和字符串的对应关系:#a#s#s#d#010121010
template for pasting manacher algorithm :
Manacher algorithm://Convert S to pre-processing of T//For example, S = "ABBA", T = "^ #a #b#b#a#$"the//^ and $ symbols are used to denote start and end, and to avoid boundary checks. stringPreprocess (strings) {intn = s.length ();if(n = =0)return "^$";stringRET ="^"; for(inti =0; I < n; i++) ret + ="#"+ S.SUBSTR (i,1); RET + ="#$";returnRET;}stringLongestpalindrome (strings) {stringT = Preprocess (s);intn = t.length ();int* P =New int[n];intC =0, R =0; for(inti =1; I < n-1; i++) {intI_mirror =2* C-I;//equals I ' = C-(i-c)P[i] = (R > i)? Min (r-i, P[i_mirror]):0;//Try to extend the center to I's Palindrome while(T[i +1+ P[i]] = = T[i-1-P[i]]) p[i]++;//If the center is a palindrome of I beyond R, according to the extended palindrome to adjust the center if(i + p[i] > R) {C = i; R = i + p[i]; } }//Find out the maximum value in P intMaxLen =0;intCenterindex =0; for(inti =1; I < n1; i++) {if(P[i] > MaxLen) {maxlen = P[i]; Centerindex = i; } }Delete[] P;//Return maximum palindrome string returnS.substr (Centerindex-1-MaxLen)/2, maxlen);}
# # #这道题的思路:
- First, the Manacher algorithm is used to process the string, the right end of the palindrome substring starting at the left end is added to the a array, and the left end of the palindrome substring with the end of the right endpoint is added to the B array (this takes full advantage of the P array obtained after the Manacher algorithm processing, according to P[i] can be transformed, The start and end of a palindrome string centered on I in the original string. Then enumerate the strings at the end of the a[i] to the left, and the string to the right of B[j], and then the P array to determine whether the string between them is a palindrome.
- It can be said that this problem is the deformation of the manacher algorithm, only fully understand the origin of the P array, it is possible to know that it has the ability to deform.
- Coding time takes a long, before you write code must have been thinking very thorough, no logic defects and then hands, so efficiency is the highest.
Code:
#include <iostream>#include <cstdio>#include <string>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <iterator>#include <cmath>#include <cstring>#include <cstdlib>using namespace STD;typedef Long LongLL;Const intINF =0x3fffffff, M =10009; vector<int>A, B, p;stringPreprocess (strings) {stringRET ="^"; for(inti =0; I < s.size (); i++) {ret + ="#"; RET + = S[i]; } ret + ="#$";returnRET;} vector<int>Manacher (stringT) { vector<int>PintR =0, z =0; for(inti =1; I < t.size ()-1; i++) {p.push_back (R > I?) Min (R-i, p[2* Z-i-1]) :0); while(T[i + p [i-1] +1] = = T[i-p[i-1] -1]) P[i-1]++;if(P[i-1] + i > R) {z = i; R = P[i-1] + i; }if(P[i-1] >=1) {intL = (I-1-P[i-1]) /2+1;intR = (I-1+ P[i-1]) /2;if(L = =1) A.push_back (R);if(r = = (T.size ()-3) /2) B.push_back (L); } }returnP;}BOOLHwintXintY) {inttemp = y-x-1;if(Temp <=0)return false;if(P[(x *2) -1+ (Y *2) -1) /2] >= temp && (p[(x *2) -1+ (Y *2) -1) /2]-Temp)%2==0)return true;return false;}intMainvoid){intTCin>> T; while(t--) {a.clear (); B.clear (); P.clear ();stringSCin>> s;//for (int i = 0; i < 100000; i++) s + = "as"; BOOLAns =false;if(S. Size () <3) {cout<<"No"<< Endl;Continue; }stringT = Preprocess (s); p = manacher (T);//for (int i = 0; i < p.size (); i++) cout << p[i] << ""; for(inti =0; I < a.size (); i++) { for(intj =0; J < B.size (); J + +) {if(A[i] < b[j]) {intx = A[i];inty = b[j];if(HW (x, y)) {ans =true;GotoL1; }}}}L1:if(ANS)cout<<"Yes"<< Endl;Else cout<<"No"<< Endl; }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 5340 Manachers + Enumeration