Problem Description One day, sailormoon girls are so delighted that

they intend to research about palindromic strings. Operation contains

two steps: First step: girls will write a long string (only contains

lower case) on the paper. For example, “abcde”, but ‘a’ inside is not

the real ‘a’, that means if we define the ‘b’ is the real ‘a’, then we

can infer that ‘c’ is the real ‘b’, ‘d’ is the real ‘c’ ……, ‘a’ is the

real ‘z’. According to this, string “abcde” changes to “bcdef”. Second

step: girls will find out the longest palindromic string in the given

string, the length of palindromic string must be equal or more than 2.

Input Input contains multiple cases. Each case contains two parts, a

character and a string, they are separated by one space, the character

representing the real ‘a’ is and the length of the string will not

exceed 200000.All input must be lowercase. If the length of string is

len, it is marked from 0 to len-1.

Output Please execute the operation following the two steps. If you

find one, output the start position and end position of palindromic

string in a line, next line output the real palindromic string, or

output “No solution!”. If there are several answers available, please

choose the string which first appears.

Sample Input

b babd
a abcd

Sample Output

0 2
aza
No solution!

思路如下

这题暴力准超时,但是还有有一种神奇的算法 Manachar 经过预处理后可以以O(n)来解决这个题

马拉车算法传送门

辅助理解转送门

Manachar代码注释

#include<iostream>
#include<string.h>
using namespace std; const int Max = 1e5;
char ar[Max]; //原始字符串
char br[Max << 2]; //存储转化后的字串
int Len[Max << 2]; //Len[i] 计算为以br[i]字符为中心的回文子串的长度,还有要注意一个规律:Len[i] - 1 为以br[i]为中心的回文子串的组成字符个数 //转换字符串
int trans_ar(char ar[])
{
int Len_ar = (int)strlen(ar);
br[0] = '@';
for(int i = 1; i <= 2 * Len_ar; i +=2)
{
br[i] = '#';
br[i + 1] = ar[i / 2];
}
br[2 * Len_ar + 1] = '#';
br[2 * Len_ar + 2] = '\0';
return 2 * Len_ar + 1;
}
//Manachar 算法过程
int Manachar(char br[],int Len_br)
{
int R = 0,mid = 0,ans = 0; //R 为当前正计算的回文中心i之前的所有回文子串,所能延伸至的最右端 的下一个数
//mid 为右端延伸至R处的回文子串的中心
for(int i = 1; i <= Len_br; i ++)
{
if(i < R)
Len[i] = min(R - i , Len[2 * mid - i]); //2 * mid - i = j ( i 与 j 关于 mid对称,根据回味子串的对称性质,我们直接让 Len[i] = Len[j] 加速查找,但是Len[j] 要小于 R - mid)
//举例证明 : c # a # c # a # b #
// 1 2 3 4 5 6 7 8 9 10
else
Len[i] = 1; //无法根据回文的性质进行加速了,只能老老实实的向两边延伸了 while(br[i - Len[i]] == br[i + Len[i]]) //向两边延伸进行判断回文半径长度
Len[i] ++; if(Len[i] + i > R) //Len[i] + i 当前以 i 为中心的回文子串所能延伸的最右端的距离
{
R = Len[i] + i;
mid = i;
}
ans = max(ans , Len[i]); //ans存储最大长度
}
return ans - 1;
} int main()
{
//freopen("test_3.txt","r",stdin);
int n;
cin>>n;
for(int i = 0; i < n; i++)
cin>>ar[i]; //转化字符串ar为br,并获取转换问之后br的长度
int Len_br = trans_ar(ar);
//求最大回文子串的长度
int ans = Manachar(br,Len_br);
cout<<ans<<endl; return 0;
}

题解如下

//hdu 3294
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std; const int Len = 200005;
char ar[Len],br[Len << 2];
int Ridus[Len << 2];
char ch; void change(char ar[])
{
int Len_ar = (int)strlen(ar);
int cha = ch - 'a';
for(int i = 0; i < Len_ar; i++)
{
ar[i] -= cha;
if (ar[i] < 'a')
ar[i] += 26;
}
} int trans_ar(char ar[])
{
int Ridus_ar = (int)strlen(ar);
br[0] = '@';
for(int i = 1; i <= 2 * Ridus_ar; i +=2)
{
br[i] = '#';
br[i + 1] = ar[i / 2];
}
br[2 * Ridus_ar + 1] = '#';
br[2 * Ridus_ar + 2] = '\0';
return 2 * Ridus_ar + 1;
} //Manachar 算法过程
int Manachar(char br[],int Ridus_br)
{
int R = 0,mid = 0,ans = 0; //R 为当前正计算的回文中心i之前的所有回文子串,所能延伸至的最右端 的下一个数
//mid 为右端延伸至R处的回文子串的中心
for(int i = 1; i <= Ridus_br; i ++)
{
if(i < R)
Ridus[i] = min(R - i , Ridus[2 * mid - i]); //2 * mid - i = j ( i 与 j 关于 mid对称,根据回味子串的对称性质,我们直接让 Ridus[i] = Ridus[j] 加速查找,但是Ridus[j] 要小于 R - mid)
else
Ridus[i] = 1; //无法根据回文的性质进行加速了,只能老老实实的向两边延伸了 while(br[i - Ridus[i]] == br[i + Ridus[i]]) //向两边延伸进行判断回文半径长度
Ridus[i] ++;
if(Ridus[i] + i > R) //Ridus[i] + i 当前以 i 为中心的回文子串所能延伸的最右端的距离
{
R = Ridus[i] + i;
mid = i;
}
ans = max(ans , Ridus[i]); //ans存储最大长度
}
return ans - 1;
} int main()
{
// freopen("test_3.txt","r",stdin);
while(cin>>ch>>ar)
{
change(ar);
int Len_br = trans_ar(ar);
int ans = Manachar(br,Len_br);
if(ans >= 2)
{
for(int i = 1;i <= Len_br; i ++)
{
if(Ridus[i] == ans + 1)
{
int st = (i - ans) / 2; //st * 2 + 2 = mid - r + 1
int ed = (i + ans - 2) / 2; //ed * 2 + 2 = mid + r - 1
cout<<st<<" "<<ed<<endl;
for(int j = i - ans; j <= i + ans; j ++)
if(br[j]>= 'a' && br[j] <= 'z')
cout<<br[j];
cout<<endl;
break;
}
}
}
else
cout<<"No solution!\n";
}
return 0;
}

Girls' research(马拉车算法) hdu 3294的更多相关文章

  1. HDU3294 Girls' research —— Manacher算法 输出解

    题目链接:https://vjudge.net/problem/HDU-3294 Girls' research Time Limit: 3000/1000 MS (Java/Others)    M ...

  2. Hdu 3294 Girls' research (manacher 最长回文串)

    题目链接: Hdu 3294  Girls' research 题目描述: 给出一串字符串代表暗码,暗码字符是通过明码循环移位得到的,比如给定b,就有b == a,c == b,d == c,.... ...

  3. (回文串 Manacher )Girls' research -- hdu -- 3294

    http://acm.hdu.edu.cn/showproblem.php?pid=3294 Girls' research Time Limit:1000MS     Memory Limit:32 ...

  4. HDU 3294 Girls' research(manachar模板题)

    Girls' researchTime Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...

  5. Manacher 算法(hdu 3068 && hdu 3294)

    今天打算补前晚 BC 的第二题,发现要用到能在 O(n) 时间求最大回文子串长度的 Manacher 算法,第一次听,于是便去百度了下,看了大半天,总算能看懂了其思想,至于他给出的代码模板我没能完全看 ...

  6. HDU - 3068 最长回文manacher马拉车算法

    # a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...

  7. 回文串--- Girls' research

    HDU   3294 Problem Description One day, sailormoon girls are so delighted that they intend to resear ...

  8. Best Reward && Girls' research

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

  9. HDU----(3294)Girls' research(manacher)

    Girls' research Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)T ...

随机推荐

  1. Pycharm IDE安装及注册激活笔记(1)

    一.Windows 下的安装及激活. 1.首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/download/#section=window ...

  2. Java避坑宝典《Java业务开发常见错误100例》上线了

    写这个专栏的缘起 之前我写过一篇博客:<朱晔的互联网架构实践心得S2E2:写业务代码最容易掉的10种坑>,引起的关注还是挺多的.后来和极客时间的编辑一拍即合决定以这个为题写一个专栏.其实所 ...

  3. 在Linux上查询物理机信息-不用去拆机器了

    目录 一.查看系统信息(包含机器型号) 1.1 查看机型和品牌 二.查看CPU 信息 2.1 查看CPU 型号 2.2 查看CPU的物理数量 2.3 查看 CPU核心数量(非逻辑CPU) 2.4 查看 ...

  4. Simulink仿真入门到精通(八) M语言对Simulink模型的自动化操作及配置

    8.1 M语言控制模型的仿真 M语言与Simulink结合的方式: 在Simulink模型或模块中使用回调函数 在M语言中调用与模型相关的命令,控制模型的建立,设置模块的属性,增删信号线,以及运行模型 ...

  5. rabitmq + php

    消费者 <?php //配置信息 $conn_args = array( 'host' => '127.0.0.1', 'port' => '5672', 'login' => ...

  6. C# MP3播放帮助类

    本文为原创文章如需转载请注明出处: /// <summary> /// ************************************************* /// 类名:M ...

  7. 【Weiss】【第03章】练习3.13:桶排序

    [练习3.13] 利用社会安全号码对学生记录构成的数组排序.编写一个程序进行这件工作,使用具有1000个桶的基数排序并且分三趟进行. Answer: 首先,对社会安全号码不了解的就把它当成一个不超过9 ...

  8. shiro框架总结

    一.概念 shiro是一个安全框架,主要可以帮助我们解决程序开发中认证和授权的问题.基于拦截器做的权限系统,权限控制的粒度有限,为了方便各种各样的常用的权限管理需求的实现,,我们有必要使用比较好的安全 ...

  9. docker-ce 在windows10下使用volume的注意事项

    最近想搭建一套CI/CD环境尝试一下,因为手里云服务太小了(1C1G),撑不起来gitlab和jenkins.恰巧年前配了台高配版的windows机器,就想在家里的机器上通过docker装gitlab ...

  10. Java 14 开箱,它真香香香香

    Java 14 已经发布有一周时间了,我准备来开个箱,和小伙伴们一起来看看新特性里面都有哪些好玩的.我们程序员应该抱着尝鲜.猎奇的心态,否则就容易固步自封,技术停滞不前.先来看看 Java 14 都有 ...