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. JAVA Hibersap 框架调用 SAP

    In this example we will create a simple Maven project which uses Hibersap to call a function in SAP ...

  2. gulpfile.js(编译sass,压缩图片,自动刷新浏览器)

    var gulp = require('gulp'),     sass = require('gulp-sass'),     watch = require('gulp-watch'),      ...

  3. js中级四: 跨域

    原文链接:http://www.cnblogs.com/scottckt/archive/2011/11/12/2246531.html 什么是跨域? 首先什么是跨域,简单地理解就是因为JavaScr ...

  4. spring 第一篇(1-1):让java开发变得更简单(上)

    1.释放POJOS能量 传统开发中是如何束缚POJOS呢,如果你开发过java很长时间,那你一定有接触过EJB的开发.那时候开发一个小小的功能都要扩展框架的类或者实现其接口.所以你很容易在早期的Str ...

  5. Java并发编程(十二)线程安全性的委托

    在组合对象中如果每个组件都已经是线程安全的,是否需要再加一个额外的"线程安全层",需要视情况而定. final可以修饰未复制的属性,只要在静态代码块或者构造函数中赋值了即可. 独立 ...

  6. driver makefile

    1.单模块单文件//*********************************************obj-m := hello.o KDIR := /home/akaedu/kernel/ ...

  7. php 使用curl 将文件上传

    <?php /**   *  curl文件上传   *  @var  struing  $r_file  上传文件的路劲和文件名     */ function upload_file($r_f ...

  8. 使用Hyper-V安装Ubuntu16.04 Server 网络配置

    由于最近在研究Docker, 于是需要用到虚拟机,安装Ubuntu 16.04到Hyper-V并部署Docker.这个过程中填平了几个小坑,为了大家以后遇到类似情况节省时间,我将这几个小坑的问题和解决 ...

  9. 自动添加需要编译的源文件Android.mk模板

    自动添加需要编译的源文件列表 添加第三方静态库.动态库的依赖   假设我们的项目依赖 libmath.a, libjson.a, libffmpeg.so 这几个第三方库文件,项目包含如下几个模块:a ...

  10. Android开发教程:shape和selector的结合使用(转载)

    shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...