最长回文字串(hdu 3068)

原题链接http://acm.hdu.edu.cn/showproblem.php?pid=3068

查找字符串中最长的回文串,我们用到manachar算法。

要实现manachar算法我们有有两步要做

1:对字符串进行处理,把所有的字符串的长度统一化为奇数。。

 1  int l=0;
 2     int ans=0;
 3     Ma[l++]=‘$‘;
 4     Ma[l++]=‘#‘;
 5     for(int i=0;i<len;i++)
 6     {
 7         Ma[l++]=s[i];
 8         Ma[l++]=‘#‘;
 9     }
10     Ma[l]=0;

例如abbba这个字符串经过处理后就变成了

$#a#b#b#b#a#

然后我们用的Mp[]表示以i为中心的(包含i这个字符)回文串半径长,然后我们就要去求Mp数组的值

假设我们扫到i+k这个位置,那么我们现在需要计算Mp[i+k],

若s[i+k]不在前面任何一个回文串中,MP[i+k]=1;

然后s[i+k]左右延伸



 while(Ma[i-Mp[i]]==Ma[Mp[i]+i]) Mp[i]++;
若是s[i+k]在之前的回文串中那么Mp[s+k]就不是从1开始了,而且Mp[i]数组有一个最小值我们设j=2*id-i;j是i关于id的对称点,下图中p数组就是Mp数组

综上所述Mp[i]=min(Mp[2*id-i],mx-i);

 
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 const int maxn=110000;
 6 char s[maxn];
 7 char Ma[maxn*2];
 8 int Mp[maxn*2];
 9 using namespace std;
10 int manachar(int len)
11 {
12     int l=0;
13     int ans=0;
14     Ma[l++]=‘$‘;
15     Ma[l++]=‘#‘;
16     for(int i=0;i<len;i++)
17     {
18         Ma[l++]=s[i];
19         Ma[l++]=‘#‘;
20     }
21     Ma[l]=0;
22     int mx=0,id=0;
23     for(int i=0;i<l;i++)
24     {
25         if(mx>i)
26         Mp[i]=min(Mp[2*id-i],mx-i);
27         else
28         Mp[i]=1;
29         while(Ma[i-Mp[i]]==Ma[Mp[i]+i]) Mp[i]++;
30         if(i+Mp[i]>mx)
31         {
32             mx=i+Mp[i];
33             id=i;
34         }
35         ans=max(ans,Mp[i]-1);
36     }
37     return ans;
38 }
39 int main()
40 {
41     while(scanf("%s",s)!=EOF)
42     {
43         int len=strlen(s);
44         int ans=manachar(len);
45         printf("%d\n",ans);
46     }
47     return 0;
48 } 

完整的AC代码

				
时间: 2024-10-10 03:28:20

最长回文字串(hdu 3068)的相关文章

Hdu 3068 最长回文字串Manacher算法

题目链接 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7976    Accepted Submission(s): 2735 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input 输入

最长回文字串理解(学习Manacher&#39;s algorithm)

关于字符串的子串问题,我们经常需要利用的是已经访问的部分的信息,来降低复杂度,和提高效率:在求最长回文子串的问题中,Manacher's algorithm提供了一种很好的机制,虽然部分地方不太容易理解 先说下核心的思想:先对原字符串进行预处理,将字符串"abc"转换为"$#a#b#c#"的形式,既避免了访问越界的问题,又保证每一个字符有至少一个对称的串(真字符,或是假的“#”) 预留两对变量(当前得到的中心位置“center”,和字符串右侧最远位置“R”,以及对称

最长回文字串 (The longest palindrome substring)

这两天去学了一下,觉得下面那篇文章写的很好,有例子,比较容易懂,所以转一下. 以下内容来自:hihoCoder: 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?” 小Ho奇怪的问道:“什么叫做最长回文子串呢?” 小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文

最长回文(hdu 3068)

Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S,两组case之间由空行隔开(该空行不用处理),字符串长度len <= 110000 Output 每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度. Sample Inpu

最长回文字串

区别于最长公共字串,下面是最长公共字串的算法,利用DP(动态规划): void LCS_dp(char * X, int xlen, char * Y, int ylen) { maxlen = maxindex = 0; for(int i = 0; i < xlen; ++i) { for(int j = 0; j < ylen; ++j) { if(X[i] == Y[j]) { if(i && j) { dp[i][j] = dp[i-1][j-1] + 1; } if

求最长回文字串

题目: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案. 示例 2: 输入: "cbbd" 输出: "bb" 知道题网上有很多种解法,比如Manacher算法就是专门解决知道题的,还有中心扩散法,小编比较水就给大家讲讲动态规划吧! dp的话,主要就是推出dp方程:以上是具体

ural 1297 O(nlogn) 后缀数组求最长回文字串

把原串复制一份反过来接在原串后面,中间用没出现过的字符隔开,然后跑后缀数组,在原创枚举每一个位为回文中心(分奇偶讨论),则回文串长度相当于原串与反串对应位置的lcp,所以先用ST预处理,然后查询.复杂度O(nlogn) #include<iostream> #include<cstring> #include<set> #include<map> #include<cmath> #include<stack> #include<

【POJ3974】最长回文字串

在这里采用的是哈希+二分的方法. 根据回文串的性质可知,可以将回文分成奇回文和偶回文分别进行处理. 对于奇回文来说,每次枚举的端点一定是重合的,因此只需计算出端点左右公共的长度是多少即可,因此二分的是以该枚举点为中心的左半边共有多少个字符. 对于偶回文来说,每次枚举的端点不一定是相等的,因此在二分的是以当前枚举点开始(包括当前枚举点)向右最多有多少个字符. 另外,之所以能够采用二分是因为当前需判断的左右串是否是回文这个问题具有单调性,即:从最大点处开始之后均不是回文,小于最大值均是回文. 在比较

算法_Longest Palindromic Substring(寻找最长回文字串)

题目:Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 题解:首先需要清楚什么是“回文“(不知道这个翻译对不对?)字符串!回文字符串关于某一个字符对称,在左右两边与中心相同距离的字符相等. 那么还需要