一、模板
算法解析:http://www.felix021.com/blog/read.php?2040
1 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为中心的最长回文,奇数回文跟偶数回文一起考虑了 2 S $ # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 # 3 P 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1 4 5 最后所求的值就是max(P[i]-1) 6 7 //输入,并处理得到字符串s,s[0]=$ 8 void getp() 9 { 10 int p[1000], mx = 0, id = 0; 11 memset(p, 0, sizeof(p)); 12 for (i = 1; s[i] != ‘\0‘; i++) 13 { 14 p[i] = mx>i ? min(p[2*id-i], mx-i) : 1; 15 while (s[i + p[i]] == s[i - p[i]]) p[i]++; 16 if (i + p[i] > mx) 17 { 18 mx = i + p[i]; 19 id = i; 20 } 21 } 22 }
二、题目
题意:输入n(1 <= n <= 100000)个人的身高hi(50 <= hi <= 250),从这些人中连续挑出k个人,这k个人【身高是左右对称的,如果是k是奇数,那么中间那个人的身高任意】&&【从左到中间那个人,身高需保证不下降,如果用H表示新队形的高度,则H[1] <= H[2] <= H[3] .... <= H[mid]】,求k的最大值。
解题思路:一般的manacher添加的是’#’,但是本题左半边的身高不递减,所以添加的应该是(h[i]+h[i+1])/2,注意细节。处理后的第奇数个身高是添加上去的,第偶数个身高是一开始输入的,当i-p[i]是奇数时,无论hh[i-p[i]]与hh[i+p[i]]是否相等,p[i]都应该+1。
比如:h[] = 80 60 70 60 90 50 ==> hh[] = -1 65 80 70 60 65 70 65 60 75 90 70 50 65【有颜色的是原串】,以70为中心时,p[6]=4而不是3
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 using namespace std; 7 const int N=2*1e5+10; 8 int h[N], hh[N]; 9 int t, n; 10 int p[N], lenhh; 11 void getp() 12 { 13 int mx = 0, id = 0; 14 memset(p, 0, sizeof(p)); 15 for (int i = 1; i<lenhh; i++) 16 { 17 p[i] = mx>i ? min(p[2*id-i], mx-i) : 1; 18 while(hh[i + p[i]] == hh[i - p[i]] && hh[i-p[i]]<=hh[i-p[i]+1]) p[i]++; 19 if((i-p[i])%2) p[i]++; 20 if (i + p[i] > mx) 21 { 22 mx = i + p[i]; 23 id = i; 24 } 25 } 26 } 27 int main(){ 28 scanf("%d", &t); 29 while(t--){ 30 scanf("%d", &n); 31 for(int i=1; i<=n; i++){ 32 scanf("%d", &h[i]); 33 } 34 h[0]=h[n], h[n+1]=h[1]; 35 lenhh=2; 36 hh[1]=(h[0]+h[1])/2, hh[0]=-1; 37 for(int i=1; i<=n; i++){ 38 hh[lenhh++]=h[i]; 39 hh[lenhh++]=(h[i]+h[i+1])/2; 40 } 41 // for(int i=0; i<lenhh; i++) cout<<hh[i]<<" "; 42 // cout<<endl; 43 getp(); 44 int maxn=0; 45 // for(int i=0; i<lenhh; i++) cout<<p[i]<<" "; 46 // cout<<endl; 47 for(int i=1; i<lenhh; i++) maxn = max(maxn, p[i]-1); 48 printf("%d\n", maxn); 49 } 50 return 0; 51 }
时间: 2024-10-06 08:32:34