• HDU3068 最长回文 <Manacher>


    最长回文

    Time Limit: 4000/2000 MS (Java/Others)
    Memory Limit: 32768/32768 K (Java/Others)

    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

    Manacher板子题。
    不懂Manacher的童鞋可以戳这里:https://segmentfault.com/a/1190000003914228
    简单来说,Manacher就是记录以每个位置为中心的回文串的半径长度,这样在后面计算的时候可以根据对称性,利用前面的结果加速,找更长匹配时暴力扩展,复杂度$O(n)$。由于此算法仅能对付长度为奇数的回文串(毕竟你算的是以每个点为中心的回文串),故先在每两个字符间插入一个占位符。

    附上AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define MAX_L 110000
    using namespace std;
    char s[MAX_L*2+5];
    int f[MAX_L*2+5];
    int manacher (char* s0) {
    	int len = strlen(s0);
    	for (int i = 0; i < len; i++)	s[i*2+1] = '#', s[i*2+2] = s0[i];
    	s[len = len*2+1] = '#';
    	int pos = 0, r = 0, ret = 0;
    	for (int i = 1; i <= len; i++) {
    		f[i] = (i < r) ? min(f[2*pos-i], r-i) : 1;
    		while (i-f[i] >= 1 && i+f[i] <= len && s[i-f[i]] == s[i+f[i]])	f[i]++;
    		if (i+f[i] > r)	pos = i, r = i+f[i];
    		ret = max(ret, f[i]-1);
    	}
    	return ret;
    }
    int main() {
    	char s0[MAX_L+5];
    	while (~scanf("%s", s0))	printf("%d
    ", manacher(s0));
    	return 0;
    }
    
  • 相关阅读:
    机器学习学习记录【持续更新】——pandas
    机器学习学习记录【持续更新】——降低损失
    Robcup2D足球学习记录【2020.01.30】
    Robcup2D足球学习记录【2020.01.18】
    Robcup2D足球学习记录【2020.01.14】
    javacript window对象
    mybatis if 语句嵌套
    hashMap 和 linkedHashMap 的区别和联系
    var let const的一些区别
    Jetty9开发(1)
  • 原文地址:https://www.cnblogs.com/AzraelDeath/p/7592833.html
Copyright © 2020-2023  润新知