HDU3068 最长回文

最长回文

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

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

这一题第一次写的时候,报Runtime Error(ACCESS_VIOLATION)错误,后来把string str;换成char str[maxn];把字符输入形式由cin>>str换成scanf(“%s”,str)(用cin很容易超时)就AC了;

代码如下:(RE代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#define maxn 110010
using namespace std;
int main(){
        string str;
    int len;
    int maxlen, id;
    int p[maxn * 2];
    int value;
    bool flag = 0;
    while (cin>>str){
        if (flag) printf("
");
        len = str.length();
        for (int i = 2 * len + 1; i>0; i -= 2){
            str[i] = '#';
            str[i - 1] = str[i / 2 - 1];
        }
        str[0] = '@';
        str[2 * len + 2] = '
';
        maxlen = 0;
        id = 0;
        value = 0;
        memset(p, 0, sizeof(p));
        for (int i = 1; i<2 * len + 1; i++){
            p[i] = maxlen>i ? min(p[2 * id - i], maxlen - i) : 1;
            while (str[i + p[i]] == str[i - p[i]]) p[i]++;
            if (maxlen<p[i] + i) {
                maxlen = p[i] + i;
                id = i;
            }
            if (value < p[i]) value = p[i] - 1;
        }
        printf("%d
", value);
    }
    return 0;
}

AC代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#define maxn 110010
using namespace std;
int main(){
    char str[maxn*2];
    int len;
    int maxlen, id;
    int p[maxn * 2];
    int value;
    bool flag = 0;
    while (scanf("%s",str)!=EOF){
        if (flag) printf("
");
        len = strlen(str);
        for (int i = 2 * len + 1; i>0; i -= 2){
            str[i] = '#';
            str[i - 1] = str[i / 2 - 1];
        }
        str[0] = '@';
        str[2 * len + 2] = '';
        maxlen = 0;
        id = 0;
        value = 0;
        memset(p, 0, sizeof(p));
        for (int i = 1; i<2 * len + 1; i++){
            p[i] = maxlen>i ? min(p[2 * id - i], maxlen - i) : 1;
            while (str[i + p[i]] == str[i - p[i]]) p[i]++;
            if (maxlen<p[i] + i) {
                maxlen = p[i] + i;
                id = i;
            }
            if (value < p[i]) value = p[i] - 1;
        }
        printf("%d
", value);
    }
    return 0;
}

以下是我觉得讲的不错的关于马拉车算法的博客:

https://blog.csdn.net/WhereIsHeroFrom/article/details/79719507

https://blog.csdn.net/xingyeyongheng/article/details/9310555

天晴了,起飞吧
原文地址:https://www.cnblogs.com/jianqiao123/p/11294935.html