hdu 3068 最长回文 (manacher)
最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 29967 Accepted Submission(s): 10950
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 29967 Accepted Submission(s): 10950
Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
aaaa
abab
Sample Output
4
3
4
3
C/C++:
1 #include <map> 2 #include <queue> 3 #include <cmath> 4 #include <vector> 5 #include <string> 6 #include <cstdio> 7 #include <cstring> 8 #include <climits> 9 #include <iostream> 10 #include <algorithm> 11 #define INF 0x3f3f3f3f 12 using namespace std; 13 const int my_max = 3e5; 14 15 char my_str[my_max], my_temp[my_max]; 16 int my_ans[my_max], len1, len2; 17 18 void manacher() 19 { 20 int id = 0, mx = 0; 21 for (int i = 2; i < len2; ++ i) 22 { 23 if (mx > i) my_ans[i] = min(mx-i, my_ans[id*2 - i]); 24 else my_ans[i] = 1; 25 while (my_temp[i - my_ans[i]] == my_temp[i + my_ans[i]]) ++ my_ans[i]; 26 if (my_ans[i] + i > mx) 27 { 28 mx = my_ans[i] + i; 29 id = i; 30 } 31 } 32 } 33 34 int main() 35 { 36 while (~scanf("%s", my_str)) 37 { 38 len1 = strlen(my_str); 39 my_temp[0] = '$'; 40 my_temp[1] = '#'; 41 for (int i = 0, j = 2; i < len1; ++ i, j += 2) 42 { 43 my_temp[j] = my_str[i]; 44 my_temp[j + 1] = '#'; 45 } 46 len2 = (len1 << 1) + 2; 47 my_temp[len2] = '*'; 48 49 manacher(); 50 int temp = 0; 51 for (int i = 2; i < len2; ++ i) 52 if (temp < my_ans[i]) 53 temp = my_ans[i]; 54 55 printf("%d\n", temp - 1); 56 } 57 58 return 0; 59 }