Manacher专题
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专题的更多相关文章
- manacher算法专题
一.模板 算法解析:http://www.felix021.com/blog/read.php?2040 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为 ...
- 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 ...
- 666 专题三 KMP & 扩展KMP & Manacher
KMP: Problem A.Number Sequence d.求子串首次出现在主串中的位置 s. c. #include<iostream> #include<stdio.h&g ...
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题解报告
来刷kuangbin字符串了,字符串处理在ACM中是很重要的,一般比赛都会都1——2道有关字符串处理的题目,而且不会很难的那种,大多数时候都是用到一些KMP的性质或者找规律. 点击标题可跳转至VJ比赛 ...
- 字符串匹配—KMP 扩展KMP Manacher
kuangbin字符串专题传送门--http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#overview 算法模板: KMP: ; ...
- HDU 4513 吉哥系列故事――完美队形II(Manacher)
题目链接:cid=70325#problem/V">[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher V - 吉哥系列故事――完美队形I ...
- 马拉车算法(Manacher's Algorithm)
这是悦乐书的第343次更新,第367篇原创 Manacher's Algorithm,中文名叫马拉车算法,是一位名叫Manacher的人在1975年提出的一种算法,解决的问题是求最长回文子串,神奇之处 ...
- [kuangbin带你飞]专题1-23题目清单总结
[kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...
- NOIP2018提高组金牌训练营——字符串专题
NOIP2018提高组金牌训练营——字符串专题 1154 回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个 ...
随机推荐
- C++语言基础(16)-string类
使用 string 类需要包含头文件<string>,下面的例子介绍了几种定义 string 变量(对象)的方法: #include <iostream> #include & ...
- TBS 手册 --phpv 翻译
为何使用它? 示例 下载 手册 支持 论坛 推荐 秀出你的站点 http://phpv.net/TBS_Manual.htm#html_automatic 网站: http://www.tinybut ...
- C - Aladdin and the Flying Carpet 有多少种长方形满足面积为a(<=10^12),且最短边>=b;长方形边长为整数,且一定不可以是正方形。
/** 题目:C - Aladdin and the Flying Carpet 链接:https://vjudge.net/contest/154246#problem/C 题意:有多少种长方形满足 ...
- centos5/6/7下yum安装zabbix-agent(被控端)
由于之前安装都是拷贝同事的zabbix_agent.tar.gz包,可是我在网上找了一大圈都没有找到这个tar包是从哪里来的,毕竟新手,太笨...so最后自己排错,找到了比较便捷的方式,直接通过yum ...
- Android ADB工具-操作手机和获取手设备信息(四)
Android ADB工具-操作手机和获取手设备信息(四) 标签(空格分隔): Android ADB 6. 其它命令 命令 功能 adb shell input text <content&g ...
- ASCII码表(0-255)
- Codeforces Beta Round #25 (Div. 2)--A. IQ test
IQ test time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...
- eclipse4.2+安装modelgoon插件,该插件支持在eclipse直接依据java文件生产类图
安装条件: 1. 确保JDK环境OK 2.该插件安装是基于eclipse kepler(4.2) (并非表示其它版本号不能安装,仅仅是博主仅仅在4.2版本号上測试了.预计4.3版本号还是支持的,可是3 ...
- ADO.NET详细学习笔记《一》
目录 ADO.NET和ADO的区别 ADO.NET的五大核心对象 Connection对象 Command对象 DataAdapter对象,DataSet对象 DataReader对象 [1]ADO. ...
- 人物FSM
人物有限状态机 之前看这个状态机没看懂,今天又翻出来,看的略懂 FSM在游戏中应用的地方还是挺多的 怪物AI,玩家行为管理 条件(包含若干事件) 条件(包含若干事件) 状态1<--------- ...