HDU 3608 最长回文 manacher算法

来源:互联网 发布:eclipse for java下载 编辑:程序博客网 时间:2024/06/02 07:14

最长回文

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24272 Accepted Submission(s): 8912

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

Source

2009 Multi-University Training Contest 16 - Host by NIT

  传说中的manacher算法。。。。
  

代码:

/**Submit Time    Judge Status    Pro.ID  Exe.Time    Exe.Memory  Code Len.   Language*2017-10-07     Accepted          3068     390MS       2940K       1072 B     G++   */#include<iostream>#include<vector>#include<string>#include<algorithm>using namespace std;string S, W;vector<int> p;void init()//预处理数据{    int len = S.length();    string &str = W;    str.resize(2 * len + 2);    str[0] = '$';//防止算法越界    int idx = 1;    for (int i = 0; i < len; i++) {        str[idx++] = '#';        str[idx++] = S[i];    }    str[idx++] = '#';}int manacher(){    init();    int maxId = 0, center = 1, len = W.length();    p.resize(len + 1);    for (int i = 1; i < len; i++) {        if (maxId > i) p[i] = min(maxId - i, p[2 * center - i]);        else p[i] = 1;        while (W[i - p[i]] == W[i + p[i]]) p[i]++;        if (p[i] + i > maxId) {            maxId = p[i] + i;            center = i;        }    }    int maxLen = 0;    for (int i = 1; i < len; i++) {        maxLen = max(p[i] - 1, maxLen);    }    return maxLen;}int main(){    cin.tie(0);    ios::sync_with_stdio(false);//不关同步会超时。。。。。    while (cin >> S) {        cout << manacher() << endl;         }    return 0;}//
原创粉丝点击