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. Thead基础及两种创建方式

    今天本人给大家讲解一下多线程,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!! 说说多线程本人自己对它理解的定义:因计算机的CPU支持能够在同一时间执行多于一 ...

  2. 网络|N1盒子做旁路由刷OpenWRT系统(小白专用)

    N1盒子做旁路由刷OpenWRT系统(小白专用) 为什么要用N1盒子 现如今新上市的路由器,市面上能买到的300元以内的路由器大多数都是双频(5G Hz和2.4G Hz)和几年前相比无论是速度还是性能 ...

  3. postman小工具

    进入lmm后,做接口测试使用的是postman,以前稍微接触过,但是不是很会用,这里就自学顺便总结一下,以便以后或者能帮助到别人,如果有什么不同的意见或者有错误,请毫不客气的指出,感谢! 推荐一篇博客 ...

  4. Drf 序列化 ModelSerializer跨表取数据

    1.对于OneToOne.Foreignkey.choices字段可以使用source取出相关信息: class CourseSerializer(serializers.ModelSerialize ...

  5. ubuntu与windows相关配置内容

    安装.配置.启动FTP服务 执行以下命令安装,安装后即会自动运行: sudo apt-get install vsftpd 修改vcftpd的配置文件/etc/vsftpd.conf,将下面几行前面的 ...

  6. 关于浏览器Number.toFixed的错误修复

    问题描述如下: var n = 1.255; var fixed = n.toFixed(2); console.log(fixed);//结果:1.25 /* 以上代码运行预期的结果是1.26,但是 ...

  7. JavaScript零宽字符

    什么是零宽字符 一种不可打印的Unicode字符, 在浏览器等环境不可见, 但是真是存在, 获取字符串长度时也会占位置, 表示某一种控制功能的字符. 常见的零宽字符有哪些 零宽空格(zero-widt ...

  8. MyBatis框架——动态SQL

    MyBatis 作为⼀个“半⾃动化”的 ORM 框架,需要开发者⼿动定义 SQL 语句. 在业务需求⽐较复杂的情 况下,⼿动拼接 SQL 语句的⼯作量会⾮常⼤,为了适⽤于不同的业务需求,往往需要做很多 ...

  9. SpringBoot源码分析(一)@SpringBootApplication解析

    @SpringBootApplication解析 三层注解 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(exclu ...

  10. vscode不能打开浏览器(Open browser failed!! Please check if you have installed the browser correctly!)

    vscode出现上述问题,我也查了很多相关资料,什么改默认浏览器设置什么的,改配置,改系统环境变量什么的,不但麻烦而且最后都难以成功. 下面分享一个可以解决的最简单办法.那就是:舍弃open in b ...