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. jvm参数设置和性能调优

    1.Java虚拟机运行时的数据区 2.常用的内存区域调节参数 -Xms:初始堆大小,默认为物理内存的1/64(<1GB):默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40% ...

  2. 【ASP.NET】——AdRotator控件

    AdRotator控件即广告控件. 广告,是站点不可缺少的一部分.也是站点获取收益的最主要途径,但最初制作广告非常麻烦.asp.net就将该方法封装成了一个控件.为我们节省了非常多时间.这也是ASP. ...

  3. hdu 1106 水

    背景:简单字符串处理,尽管有点绕. #include<cstdio> #include<iostream> #include<cstring> #include&l ...

  4. Linux虚拟机Centos 设置固定的静态IP

    经过两天的研究(研究到深夜1点),百度了很多文章与加了几个linux的群,终于得到一种方式是可以正常设置静态IP且正常的ssh连接的方式. 第一种方式:NAT模式 参考文章 -- 虚拟机中的CentO ...

  5. Windows下使用python

    Windows下使用python,一般安装python就有IDLE了,再这个里面使用就好了,很方便 安装完之后.py的文件右键会有Edit with IDLE,可是我脑残想要默认打开就是IDLE,结果 ...

  6. js实现pdf对页面的打印

    //-------------------------------点击打印的图标--------------------------------- <div class="dcsc&q ...

  7. c 编译异常 switch 之a label can only be part of a statement and a declaration is not a statement

    client.c:996: error: a label can only be part of a statement and a declaration is not a statement sw ...

  8. Unity3D学习笔记——NGUI之UIGrid

    UIGrid:这个组件可以轻松的让你排列你的组件,并且在运行或是编辑的时候都可以. 效果图如下: 一:使用步骤 1.选择一个panel然后右键Create——Grid 2.为Grid创建几个子Spri ...

  9. Unity3D学习笔记——NGUI之UISlider

    UISlider:用于创建简单的滑动块和进度条,并且可以添加一个拇指按钮. 效果图如下: 一:使用步骤 1.从上面的效果看出,这个工具由四部分组成:背景图,进度图,进度lable显示,拇指按钮. 2. ...

  10. windows下用py2exe打包脚本为可双击运行程序

    文件夹结构: ├── readme.txt ├── settings.py #程序参数 ├── settings.pyc ├── setup.py    #安装文件 ├── spider.ico   ...