题目链接
最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 25520 Accepted Submission(s): 9422
Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S 两组case之间由空行隔开(该空行不用处理) 字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa abab
Sample Output
4 3
manacher算法的模板题目,可以在O(n)时间内计算出最长的回文串,算法讲解如下
#include#include #include #include using namespace std;const int maxn = 110050;char s1[maxn], s2[maxn * 2];int p[maxn * 2], ans;//把'abab\0'这种普通的字符串变成'$a#b#a#b#\0'便于计算void init() { ans = 0; s2[0] = '$'; s2[1] = '#'; int i, j; for (i = 0, j = 2; s1[i]; ++i, ++j) { s2[j] = s1[i]; s2[++j] = '#'; } s2[j] = '\0';}void manacher() { memset(p, 0, sizeof(p)); int id = 0, mx = 1;//初始化条件 for (int i = 1; s2[i]; ++i) {//p[0]不需要处理 p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1; while (s2[i - p[i]] == s2[i + p[i]]) ++p[i]; if (i + p[i] > mx) { mx = i + p[i]; id = i; } ans = max(ans, p[i] - 1); }}int main() { while (scanf("%s", s1) == 1) { init(); manacher(); printf("%d\n", ans); } return 0;}