先上题目:
最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7899 Accepted Submission(s): 2703
Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
abab
Sample Output
4
3
做法:使用manacher算法求最长回文串。这玩意有一个优点,可以统一处理奇数或者偶数的回文串,不用分开讨论。
首先将每一个字符用一个分隔符隔开(例如'#'),当然,字符串的开头和结尾都要加分隔符。然后再求出为一个位置为中间的最长回文串一条臂的长度p[i],那么原串中以这一个字符为中心的的回文的长度等于p[i]-1。
具体实现过程看代码。值得注意的是根据manacher求出的st并不是最长回文串的起始位置,所以需要再扫描一遍p[]求出最大值。
上代码:
1 #include <cstdio> 2 #include <cstring> 3 #define min(x,y) (x < y ? x : y) 4 #define MAX 110002 5 using namespace std; 6 7 char s[MAX<<1],c[MAX]; 8 int p[MAX<<1]; 9 10 int get(int &k){ 11 s[0]='$';s[1]='#'; k=2; 12 while((s[k]=getchar())!=EOF) { 13 if(s[k]==' '){ 14 s[k]='