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. vijos 1449 字符串还原

    背景 小K是一位蔚蓝教主的崇拜者(Orz教主er),有一天,他收到了一封匿名信,信告诉了小K由于他表现出色,得到了一次当面Orz教主的机会,但是要当面Orz教主可不那么容易,不是每个人都有资格Orz教 ...

  2. (数据科学学习手札79)基于geopandas的空间数据分析——深入浅出分层设色

    本文对应代码和数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 通过前面的文章,我们已经对geopanda ...

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

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

  4. Spring源码阅读笔记05:自定义xml标签解析

    在上篇文章中,提到了在Spring中存在默认标签与自定义标签两种,并且详细分析了默认标签的解析,本文就来分析自定义标签的解析,像Spring中的AOP就是通过自定义标签来进行配置的,这里也是为后面学习 ...

  5. ES6整体内容

    ES6内容: 附网站链接:http://www.jscwwd.com/article/5e6488e849a13d1a89caf574

  6. vux中表单验证,在提交时自动聚焦到未验证通过的那栏;及循环表单的验证

    首先vux中的表单验证在点击触发,失焦时才显示错误信息,如果不管它,它就没反应,这显然是不合理的:解决办法就是:在提交时做验证,不通过的话就使用.focus()及.blur()方法给它聚焦,失焦. i ...

  7. ui自动化chrome文件上传操作

    web自动化,再chrome浏览器中文件上传操作

  8. 程序员找工作必备 PHP 基础面试题

    1.优化 MYSQL 数据库的方法 (1) 选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置 NOT NULL, 例如’省份,性别’, 最好设置为 ENUM (2) 使用连接(JOIN)来 ...

  9. Android UI性能测试——使用 Systrace 查找问题

    一 官方文档翻译 官文地址:https://developer.android.com/studio/command-line/systrace systrace命令允许您在系统级别上收集和检查所有运 ...

  10. springcloud基础-eureka(注册中心)案例

    一.新建项目,取名eureka-server pom.xml <?xml version="1.0" encoding="UTF-8"?> < ...