最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7976 Accepted Submission(s): 2735Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
abab
Sample Output
4
3
关于Manacher算法的介绍,网上可以找到很多资料。O(N)
Accepted Code:
1 /************************************************************************* 2 > File Name: hdu_3068.cpp 3 > Author: Stomach_ache 4 > Mail: [email protected] 5 > Created Time: 2014年08月04日 星期一 18时44分05秒 6 > Propose: hdu3068, poj3974 7 ************************************************************************/ 8 // Manacher O(n) 9 #include <cmath> 10 #include <string> 11 #include <cstdio> 12 #include <fstream> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 const int maxn = 100005; 19 char s[maxn], str[maxn<<1]; 20 int p[maxn<<1], n; 21 22 void Manacher() { 23 n = strlen(s); 24 str[0] = ‘$‘; 25 str[1] = ‘#‘; 26 for (int i = 0; i < n; i++) { 27 str[i*2+2] = s[i]; 28 str[i*2+3] = ‘#‘; 29 } 30 n = n * 2 + 2; 31 str[n] = 0; 32 33 int mx = 0; 34 int id; 35 for (int i = 1; i < n; i++) { 36 if (mx > i) p[i] = min(p[2*id-i], mx - i); 37 else p[i] = 1; 38 for ( ;str[i-p[i]] == str[i+p[i]]; p[i]++); 39 if (p[i] + i > mx) { 40 mx = p[i] + i; 41 id = i; 42 } 43 } 44 } 45 46 void solve() { 47 Manacher(); 48 int ans = 0; 49 for (int i = 0; i < n; i++) ans = max(ans, p[i]); 50 printf("%d\n", ans - 1); 51 } 52 53 int main(void) { 54 while (~scanf("%s", s)) { 55 solve(); 56 } 57 58 return 0; 59 }
Hdu 3068 最长回文字串Manacher算法
时间: 2024-10-17 17:59:23