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 个 ...
随机推荐
- 内核并发管理---spin lock
自旋锁最初是为了在smp系统上使用而设计. 1.在单处理器非抢占模式下,自旋锁不做任何事情. #ifdef CONFIG_PREEMPT_COUNT //支持抢占模式 #define pree ...
- objc_runtime使用方法的几个简单例子(转)
1. 给NSObject类动态添加属性h定义部分 [cpp] @interface UIWebView (LoadProgress) @property (nonatomic, assign) NS ...
- eclipse中使用jetty启动项目
eclipse里修改 Goals值 Tomcat -Dmaven.tomcat.port=8080 tomcat:run Jetty -Djetty.port=8081 jetty:run
- Java并发编程(九)安全发布
之前讨论是如何将对象封闭在线程之中,这样可以减少一些并发带来的同步和可见性问题.但是在有些时候,我们希望在多个线程间共享对象,此时必须确保安全地进行共享. [不安全发布的示例] 可见性问题:其他线程看 ...
- redis主从备份
redis主从备份,默认是读写分离的,master用于写,slave用于读.slave的写只能用于存储一些短暂状态的变量,应为在下次同步时,会被移除. 配置主从备份原则:配从不配主,既只需修改从库配置 ...
- GCD XOR UVA 12716 找规律 给定一个n,找多少对(a,b)满足1<=b<=a<=n,gcd(a,b)=a^b;
/** 题目:GCD XOR UVA 12716 链接:https://vjudge.net/problem/UVA-12716 题意:给定一个n,找多少对(a,b)满足1<=b<=a&l ...
- php 常面试
问题:请用最简单的语言告诉我PHP是什么? 回答:PHP全称:Hypertext Preprocessor,是一种用来开发动态网站的服务器脚本语言. 问题:什么是MVC? 回答:MVC由Model(模 ...
- 一个基于 EasyUI 的前台架构(3)封装操作Tabs的JS代码
一般来说,系统框架的主内容区会引入另一个独立的 Web 页面来实现系统的功能,所以在在 Tabs 里的每一个标签页里使用 iframe 标签来引入子页面.所以这里可以将 Tabs 的 Content ...
- asp.net 关于字符串内范围截取的一点方法总结
前两天有一位网友提出了一个字符串内截取字符串的问题,除了用普通的字符串截取的方式外,我推荐的是用LINQ方式来截取.两者实际上差别不是很大,都是采用字符串截取方式,但后者从写法和观察效果会比前者简单实 ...
- centos7 更换yum源为阿里云
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup curl -o /etc/yum.repos ...