Girls' research(马拉车算法) hdu 3294
文章目录
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的更多相关文章
- HDU3294 Girls' research —— Manacher算法 输出解
题目链接:https://vjudge.net/problem/HDU-3294 Girls' research Time Limit: 3000/1000 MS (Java/Others) M ...
- Hdu 3294 Girls' research (manacher 最长回文串)
题目链接: Hdu 3294 Girls' research 题目描述: 给出一串字符串代表暗码,暗码字符是通过明码循环移位得到的,比如给定b,就有b == a,c == b,d == c,.... ...
- (回文串 Manacher )Girls' research -- hdu -- 3294
http://acm.hdu.edu.cn/showproblem.php?pid=3294 Girls' research Time Limit:1000MS Memory Limit:32 ...
- HDU 3294 Girls' research(manachar模板题)
Girls' researchTime Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...
- Manacher 算法(hdu 3068 && hdu 3294)
今天打算补前晚 BC 的第二题,发现要用到能在 O(n) 时间求最大回文子串长度的 Manacher 算法,第一次听,于是便去百度了下,看了大半天,总算能看懂了其思想,至于他给出的代码模板我没能完全看 ...
- HDU - 3068 最长回文manacher马拉车算法
# a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...
- 回文串--- Girls' research
HDU 3294 Problem Description One day, sailormoon girls are so delighted that they intend to resear ...
- Best Reward && Girls' research
After an uphill battle, General Li won a great victory. Now the head of state decide to reward him w ...
- HDU----(3294)Girls' research(manacher)
Girls' research Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)T ...
随机推荐
- 必备技能三、render渲染函数
Vue 推荐使用在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template ...
- Ajax同步和异步的区别?
今天在code review时候看到同事的代码,用了ajax同步,async:false,如果不设置async参数,默认是true,为异步,异步的情况是比较复杂的,看下同步这个例子: function ...
- 1..Net平台的背景
一:.Net平台的背景 1. 2010之前 的PC时代的时候,互联网规模还不是特别庞大,以静态编译式语言为代表的JAVA和.Net没什么太大区别,.net以windows自居. 2. 2010年以JA ...
- 原生js实现随着滚动条滚动,导航会自动切换的效果
最近学习前端,把前面用原生js写的一段有关tab切换效果的代码贴上,实现的效果比较简陋,请大家见谅 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...
- 通过实现简单聊天室了解websocket的基础使用
websocket基础使用 用到的依赖包 websocket的依赖 <dependency> <groupId>javax.websocket</groupId> ...
- 小白学 Python 数据分析(16):Matplotlib(一)坐标系
人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...
- Linux查看目录树形结构
安装tree. yum -y install tree 查看是否安装成功 yum list installed tree 执行tree命令查看目录树形结构 tree
- dos下 批处理 用 pause 可以在最后暂停 查看结果信息 build.bat
dos下 批处理 用 pause 可以在最后暂停 查看结果信息
- 【Weiss】【第03章】链表例程
这种基础例程,如之前所提,会有一个实现和一个简单的测试代码. 链表其实没什么可说的,其实包括后面的栈和队列也没什么可说的,直接放代码吧. 下面这个是测试代码 #include <iostream ...
- 114 Flatten Binary Tree to Linked List [Python]
114 Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-place. 将二 ...