1、POJ 3974 Palindrome

  题意:求一个长字符串的最长回文子串。

  思路:Manacher模板。

 #include<iostream>
#include<algorithm>
using namespace std;
const int maxn = ;
char s[maxn];
char tmp[ * maxn + ];
int p[ * maxn + ];
int Manacher(char *s,char *tmp,int *p, int &start)
{////s原字符串,tmp转换后的字符串,p记录长度
//char s[maxn];
//char tmp[2 * maxn + 3];
//int p[2 * maxn + 2];
//将所有可能的奇数 / 偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如$#a#b#a#
int n = strlen(s);
for (int i = ; i < * n + ; i++)
{
if (i == ) tmp[i] = '$';
else if (i % ) tmp[i] = '#';
else tmp[i] = s[i / - ];
}
tmp[ * n + ] = '\0'; memset(p, , sizeof(p)); int len = * n + ;
int i = , mx = , id, ans = ;//id表示最大回文子串中心的位置,mx则为id+P[id],也就是最大回文子串的边界,即回文串最右边字符的最大值
start = ;
for (i = ; i < len; i++)
{
if (mx > i) p[i] = min(p[ * id - i], mx - i);//在Len[j]和mx-i中取个小
else p[i] = ;//如果i>=mx,要从头开始匹配
while(tmp[i + p[i]] == tmp[i - p[i]])p[i]++;
if (p[i] + i > mx) mx = p[i] + i, id = i;//若新计算的回文串右端点位置大于mx,要更新id和mx的值
if (p[i] - > ans)//返回Len[i]中的最大值-1即为原串的最长回文子串额长度
{
ans = p[i] - ;
start = (i - (p[i] - )) / - ;
}
}
return ans;
} int main()
{
int t = ;
while (~scanf("%s", s))
{
if (s[] == 'E')break;
int st = ;
int ans = Manacher(s, tmp, p, st);
printf("Case %d: %d\n",t++, ans);
}
return ;
}

2、HDU 4513 吉哥系列故事――完美队形II

  题意:求最长回文数字子串,且左右向中间递增。

  思路:manacher基础算法上加个判定条件:即向两边延伸的大小限制。

 #include<iostream>
#include<algorithm>
using namespace std;
const int maxn = ;
int s[maxn];
int tmp[ * maxn + ];
int p[ * maxn + ];
int n;
int Manacher(int *s, int *tmp, int *p, int &start)
{////s原字符串,tmp转换后的字符串,p记录长度
//char s[maxn];
//char tmp[2 * maxn + 3];
//int p[2 * maxn + 2];
//将所有可能的奇数 / 偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如$#a#b#a#
for (int i = ; i < * n + ; i++)
{
if (i == ) tmp[i] = -;
else if (i % ) tmp[i] =;
else tmp[i] = s[i / - ];
}
//tmp[2 * n + 2] = '\0'; memset(p, , sizeof(p)); int len = * n + ;
int i = , mx = , id, ans = ;//id表示最大回文子串中心的位置,mx则为id+P[id],也就是最大回文子串的边界,即回文串最右边字符的最大值
start = ;
for (i = ; i < len; i++)
{
if (mx > i) p[i] = min(p[ * id - i], mx - i);//在Len[j]和mx-i中取个小
else p[i] = ;//如果i>=mx,要从头开始匹配
while (tmp[i + p[i]] == tmp[i - p[i]]&&tmp[i+p[i]]<=tmp[i+p[i]-])p[i]++;
if (p[i] + i > mx) mx = p[i] + i, id = i;//若新计算的回文串右端点位置大于mx,要更新id和mx的值
if (p[i] - > ans)//返回Len[i]中的最大值-1即为原串的最长回文子串额长度
{
ans = p[i] - ;
start = (i - (p[i] - )) / - ;
}
}
return ans;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (int i = ; i < n; i++) scanf("%d", &s[i]);
int st;
int ans = Manacher(s, tmp, p, st);
printf("%d\n", ans);
} return ;
}

3、hdu 3294 Girls' research

  题意:给出一个字符串,然后给出转换字符C(表示C代表真正的‘a’),然后求转换后的字符串的大于等于2的最长回文子串。

  思路:其实可以先求处原字符串的最长回文子串,再转换输出即可。

 #include<iostream>
#include<algorithm>
using namespace std;
const int maxn = ;
char s[maxn];
char tmp[ * maxn + ];
int p[ * maxn + ];
int Manacher(char *s, char *tmp, int *p, int &start)
{////s原字符串,tmp转换后的字符串,p记录以tmp[i]为中心的最长回文子串的最右端到tmp[i]的位置的长度
//char s[maxn];
//char tmp[2 * maxn + 3];
//int p[2 * maxn + 2];
//将所有可能的奇数 / 偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如$#a#b#a#
int n = strlen(s);
for (int i = ; i < * n + ; i++)
{
if (i == ) tmp[i] = '$';
else if (i % ) tmp[i] = '#';
else tmp[i] = s[i / - ];
}
tmp[ * n + ] = '\0'; memset(p, , sizeof(p));
int len = * n + ;
int i = , mx = , id, ans = ;//id表示最大回文子串中心的位置,mx则为id+P[id],也就是最大回文子串的边界,即回文串最右边字符的最大值
start = ;
for (i = ; i < len; i++)
{
if (mx > i) p[i] = min(p[ * id - i], mx - i);//在Len[j]和mx-i中取个小
else p[i] = ;//如果i>=mx,要从头开始匹配
while (tmp[i + p[i]] == tmp[i - p[i]])p[i]++;
if (p[i] + i > mx) mx = p[i] + i, id = i;//若新计算的回文串右端点位置大于mx,要更新id和mx的值
if (p[i] - > ans||(p[i]-==ans&& (i - (p[i] - )) / - <start))//返回Len[i]中的最大值-1即为原串的最长回文子串额长度
{
ans = p[i] - ;
start = (i - (p[i] - )) / - ;
}
}
return ans;
} int main()
{
char c;
while (cin>>c)
{
scanf("%s", s);
int st = ;
int ans = Manacher(s, tmp, p, st);
if (ans >= )
{
printf("%d %d\n", st,st+ans-);
for (int i = st; i < st + ans; i++)printf("%c", ('a'+s[i]+-c)>'z'? 'a' + s[i]- c: 'a' + s[i] + - c);
printf("\n");
}
else printf("No solution!\n"); }
return ;
}

Manacher专题的更多相关文章

  1. manacher算法专题

    一.模板 算法解析:http://www.felix021.com/blog/read.php?2040 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为 ...

  2. kuangbin专题十六 KMP&&扩展KMP HDU3613 Best Reward(前缀和+manacher or ekmp)

    After an uphill battle, General Li won a great victory. Now the head of state decide to reward him w ...

  3. 666 专题三 KMP &#38; 扩展KMP &#38; Manacher

    KMP: Problem A.Number Sequence d.求子串首次出现在主串中的位置 s. c. #include<iostream> #include<stdio.h&g ...

  4. [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题解报告

    来刷kuangbin字符串了,字符串处理在ACM中是很重要的,一般比赛都会都1——2道有关字符串处理的题目,而且不会很难的那种,大多数时候都是用到一些KMP的性质或者找规律. 点击标题可跳转至VJ比赛 ...

  5. 字符串匹配—KMP 扩展KMP Manacher

    kuangbin字符串专题传送门--http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#overview 算法模板: KMP: ; ...

  6. HDU 4513 吉哥系列故事――完美队形II(Manacher)

    题目链接:cid=70325#problem/V">[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher V - 吉哥系列故事――完美队形I ...

  7. 马拉车算法(Manacher's Algorithm)

    这是悦乐书的第343次更新,第367篇原创 Manacher's Algorithm,中文名叫马拉车算法,是一位名叫Manacher的人在1975年提出的一种算法,解决的问题是求最长回文子串,神奇之处 ...

  8. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

  9. NOIP2018提高组金牌训练营——字符串专题

    NOIP2018提高组金牌训练营——字符串专题 1154 回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式.   a|bb|aabaa - 3 个 ...

随机推荐

  1. Python内置函数之open()

    open(file, mode=, encoding=None, errors=None, newline=None, closefd=True, opener=None) 打开一个文件,返回一个对应 ...

  2. swoole-1.7.18 版本已发布,支持 PHP7

    swoole-1.7.18 版本已发布,支持 PHP7 matyhtf 发布于: 2015年07月23日 (22评) 分享到:    收藏 +16 3月19日,深圳源创会火热报名中,go>> ...

  3. 李洪强iOS开发之OC[006] - 类和对象

  4. 转载-好用的linux软件合集

    音频 Airtime – Airtime 是一款用于调度和远程站点管理的开放广播软件  Ardour – 在 Linux 上录音,编辑,和混音  Audacious – 开源音频播放器,按你想要的方式 ...

  5. java - day05 - Array

    /* 生成随机数组,寻找最大值 */ package day05; public class ArrayGuess { public static void main(String args[]) { ...

  6. c#的bug?

    在群里面有人提出了这么一个诡异的问题,请问15.5%3.1=? 然后,我就去看了看,因为他们说结果是3.1!!!

  7. C# 子类实例化过程

    刚研究了一下C#子类实例化的过程. 首先我遇到了如下一个问题: 有类A,里面写了一个有参的构造函数,并没有提供默认的无参构造函数.现在类B继承了类A,没有写任何的构造函数. 这时如果想实例化类B就会产 ...

  8. linux mount-umount命令常用记录

    每次挂在u盘都忘记,这次记录下. umount命令: 必杀:umount -l /dev/sda1 (有时候卸载不能卸,加-l(不是1,是小写字母l)参数,表示在设备不忙时卸载设备,就可成功卸载设备) ...

  9. centos6.5下redis的安装与配置

    参照官网描述(https://redis.io/download),linux下redis安装步骤如下: $ wget http://download.redis.io/releases/redis- ...

  10. 第二百节,jQuery EasyUI,Tabs(选项卡)组件

    jQuery EasyUI,Tabs(选项卡)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 5.选项卡面板 本节课重点了解 EasyUI 中 Tabs(选项卡)组件的使用方 ...