题目描述:Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

输入描述:输入一个字符串

输出描述:返回有效密码串的最大长度

输入例子:

ABBA

输出例子:

4

思路:最长回文串的长度

Manacher算法O(n)

因为对于偶回文,是需要从虚轴扩充,ab,ba,所以如下:

先把原字符串处理,都加上一个标记符,比如#(特殊字符任何都可以,对于计算结果不会有影响)

1221-->#1#2#2#1#

121-->#1#2#1#

按照处理后的字符串求它的最长回文串长度m,所以原始字符串最长子回文串的长度是m/2

变量:

1:PArra[] 存放回文半径:某个位置能扩充的回文半径的长度,例如 #1#2#2#1#,2位置PArra[3] = 4

2:int PR 能够扫到的最右的回文的位置   #1#2#1# 在位置3   PR = 6

3:int  index   当 PR更新的时候,index也要更新,指向当前最中心的位置   2中index=3

过程:

当要求位置i的时候的回文半径   分析如下:

1:第一种情况可以直接确定i的回文半径,PR不变,因为没有扩

2:第二种情况,i'的左边在index左边的左边,PR不用变化,(没有扩)也可以直接确定i位置的回文半径

3:第三种情况,i'的左边喝index的左边重复,需要从  “右大位置开始继续扩”

如何算复杂度:

如果扩成功了,说明,超过了目前的右大更新PR

4:第四种情况必须暴力扩

每一次检查的时候,要么失败,要么成功扩,只要成功扩了,PR必须更新,而且最长扩也就2n,所以“扩”的动作和PR高度相关;

通过变量优化这个算法的时候,一般这个复杂度和这个变量的增量有关。

 import java.util.Scanner;

 public class Main {

     public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNextLine())
{
String input = in.nextLine();
char[] inputChar = input.toCharArray();
StringBuilder sb = new StringBuilder();
sb.append("#");
//重新构造原来字符串
for(int i = 0; i < input.length(); i++)
{
sb.append(inputChar[i]);
sb.append("#");
}
int length = sb.length();
char[] newChar = new char[length];//
int pArray[] = new int[length];//记录以每个新的字符为中心的最大回文串长度
newChar = sb.toString().toCharArray();
int pr = 0;//当前回文串最右边的字符的下标,同时也是一个最大值,因为每一次针对i位置的回文串长度都可以利用上一步的结果,所以pr一直在增加
int index = 0;//当前回文串的中间值下标
int count = 0;//记录最大回文
for(int i = 0; i< newChar.length; i++)
{
//如果i位置在当前pr之内(左边),可以不用扩充,直接得知i位置的最长回文串
if(pr > i)
{
//两个参数代表两种情况,一种i对应index的左边的i'的回文串最左在index最左的左边,一种是在右边
pArray[i] = Math.min(pArray[2*index - i], pr-i);
}
//否则初始化为1
else
{
pArray[i] = 1;
}
//到位置i,往前往后判断是否是回文,不断更新pArray[i]
while(i-pArray[i] >= 0 && i+pArray[i] < newChar.length && newChar[i-pArray[i]] == newChar[i+pArray[i]])
{
pArray[i]++;
}
//更新最右下标和index
if(pr<i+pArray[i])
{
pr = i+pArray[i];
index = i;
}
count = Math.max(count, pArray[i]-1);
}
System.out.println(count);
}
} }

37:密码截取(回文串manacher算法)的更多相关文章

  1. luoguP4555 [国家集训队]最长双回文串 manacher算法

    不算很难的一道题吧.... 很容易想到枚举断点,之后需要处理出以$i$为开头的最长回文串的长度和以$i$为结尾的最长回文串的长度 分别记为$L[i]$和$R[i]$ 由于求$R[i]$相当于把$L[i ...

  2. bzoj 2565: 最长双回文串 manacher算法

    2565: 最长双回文串 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...

  3. 最长回文---hdu3068 (回文串 manacher 算法模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意很清楚:就是求一个串s的子串中最长回文串的长度:这类题用到了manacher算法 #incl ...

  4. 【BZOJ2565】最长双回文串 (Manacher算法)

    题目: BZOJ2565 分析: 首先看到回文串,肯定能想到Manacher算法.下文中字符串\(s\)是输入的字符串\(str\)在Manacher算法中添加了字符'#'后的字符串 (构造方式如下) ...

  5. UESTC-1975弗吉桑(回文串,manacher算法)

    弗吉桑 Time Limit: 3000 MS     Memory Limit: 64 MB Submit Status 弗吉桑是一座横跨清水河大草原的活火山,位于子科技大学主楼东北方约 80km ...

  6. 回文串--Manacher算法(模板)

    用途:在O(n)时间内,求出以每一个点为中心的回文串长度. 首先,有一个非常巧妙的转化.由于回文串长度有可能为奇数也有可能为偶数,说明回文中心不一定在一个字符上.所以要将字符串做如下处理:在每两个字母 ...

  7. HDU3068 回文串 Manacher算法

    好久没有刷题了,虽然参加过ACM,但是始终没有融会贯通,没有学个彻底.我干啥都是半吊子,一瓶子不满半瓶子晃荡. 就连简单的Manacher算法我也没有刷过,常常为岁月蹉跎而感到后悔. 问题描述 给定一 ...

  8. Palindrome(最长回文串manacher算法)O(n)

     Palindrome Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  9. 九度OJ 1528 最长回文子串 -- Manacher算法

    题目地址:http://ac.jobdu.com/problem.php?pid=1528 题目描述: 回文串就是一个正读和反读都一样的字符串,比如"level"或者"n ...

随机推荐

  1. 利用Docker搭建本地https环境的完整步骤

    利用Docker搭建本地https环境的完整步骤 这篇文章主要给大家介绍了关于如何利用Docker搭建本地https环境的完整步骤,文中通过示例代码将实现的步骤介绍的非常详细,对大家的学习或者工作具有 ...

  2. HDU3538 A sample Hamilton path

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  3. VIjosP1046观光旅游

    背景 湖南师大附中成为百年名校之后,每年要接待大批的游客前来参观.学校认为大力发展旅游业,可以带来一笔可观的收入. 描述 学校里面有N个景点.两个景点之间可能直接有道路相连,用Dist[I,J]表示它 ...

  4. 怎样让enum枚举支持string

    原文发布时间为:2011-03-02 -- 来源于本人的百度文章 [由搬家工具导入] 大家都知道enum是以下两种情况,不能支持string 1,enum类型是静态 2,enum类型仅限于long、i ...

  5. java 修改字体大小

    在Windows->Preferences->General->Appearance->Colors and Fonts->Java->Java Editor Te ...

  6. FZU 1078 计算循环冗余码【模拟】

    计算机网络中采用循环冗余码来校验数据的正确性.其原理是:发送方计算出待发送的二进制数据的循环冗余码,并随同原数据一起发送到接收方:接收方通过重新计算接收到的数据的循环冗余码,并和收到的循环冗余码进行比 ...

  7. 2017广东工业大学程序设计竞赛决赛 F(LCA + 斐波那契数列性质)

    不能组成三角形的极端数列:1,1,2,3,5,8,13,21,……到第50项时候肯定到1e9了…… 如果两个点之间距离大于50,则直接Yes…… 否则的话直接暴力取出所有边,然后升序排序,判断一下就可 ...

  8. 关于npm无法安装依赖包以及安装包缓慢的解决方法

    因为npm的服务器在国外,导致我们使用npm安装第三方包缓慢.而且有的第三方包是被墙的. 因此,作为墙内人,必须解决这个问题,否则开发起来实在是太坑了! 推荐大家使用淘宝的镜像(cnpm),它以每10 ...

  9. NOI模拟题1 Problem A: sub

    题面 Sample Input 5 7 2 -1 -3 1 1 1 2 1 3 3 4 3 5 2 1 3 0 2 1 2 1 2 1 1 -3 2 Sample Output 2 4 5 2 HIN ...

  10. noip2017集训测试赛(三)Problem C: MST

    题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大, ...