题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3294
给出一个字符串和加密的字符规律
例如 c abcba
c代表把串中的c改成a,d改成b... b改成z,a改成y...
即上串是yzazy,然后求出它的最长回文子串, 并记录子串的开始下标和结束下标就行了;
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N = 4e5+7; int p[N], id, mx, ans, Index; char s[N], ch[5], s0[N]; void Manacher(char s[], int n) { id = mx = ans = 0; for(int i=2; i<n; i++) { if(mx>i) p[i] = min(p[id*2-i], mx-i); else p[i] = 1; while(s[i-p[i]] == s[i+p[i]]) p[i]++; if(p[i]+i>mx) { mx = p[i]+i; id = i; } if(p[i]>ans) { ans = p[i]; Index = i;///记录结果的中心下标; } } } int main() { while(scanf("%s%s", ch, s)!=EOF) { int len = strlen(s); int k = ch[0]-‘a‘; for(int i=0; i<len; i++)///转化成真正的串s; { if(s[i]-k<‘a‘) s[i]=s[i]-k+26; else s[i]=s[i]-k; } ///printf("%s\n", s); for(int i=len; i>=0; i--) { s[i+i+2] = s[i]; s[i+i+1] = ‘#‘; } s[0] = ‘$‘; Manacher(s, 2*len+2); ans = ans-1; k = ans/2;///前面或后面有几个字母在回文串中; if(k == 0) { printf("No solution!\n"); continue; } int L = Index-ans+1; int R = Index+ans-1; printf("%d %d\n", (L-2)/2, (R-2)/2); for(int i=L; i<=R; i++) if(s[i]!=‘#‘) printf("%c", s[i]); printf("\n"); } return 0; }
Girls' research---hdu3294(回文子串manacher)
时间: 2024-10-29 19:06:12