版权声明:转载时 别忘了注明出处 https://blog.csdn.net/ZCY19990813/article/details/89277708
链接:https://ac.nowcoder.com/acm/contest/549/B
来源:牛客网
题目描述
小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的。所以小A只想知道给定的一个字符串的最大回文子串是多少,但是小A对这个结果并不是非常满意。现在小A可以对这个字符串做一些改动,他可以把这个字符串最前面的某一段连续的字符(不改变顺序)移动到原先字符串的末尾。那么请问小A通过这样的操作之后(也可以选择不移动)能够得到最大回文子串的长度是多少。
输入描述:
一行一个字符串表示给定的字符串S一行一个字符串表示给定的字符串S
输出描述:
一行输出一个整数,表示通过这样的操作后可以得到最大回文子串的长度。
链接:https://ac.nowcoder.com/acm/contest/549/B
来源:牛客网
示例1
输入
dcbaabc
输出
7
说明
将前面的dcba移动到末尾变成abcdcba,这个字符串的最大回文子串就是它本身,长度为7
备注:
N表示字符串的长度,1≤N≤5000
思路:数据量较小,直接暴力求解,将字符串移动len次,每次都遍历。那问题来了,怎么求一个字符串中最长的回文子串呢,那就用到Manacher了。
先来一个Manacher的模板:
const int MAXN=110010;
char Ma[MAXN*2];
int Mp[MAXN*2];
void Manacher(char s[],int len)
{
int l=0;
Ma[l++]='$';
Ma[l++]='#';
for(int i=0; i<len; i++)
{
Ma[l++]=s[i];
Ma[l++]='#';
}
Ma[l]=0;
int mx=0,id=0;
for(int i=0; i<l; i++)
{
Mp[i]=mx>i?min(Mp[2*id − i],mx − i):1;
while(Ma[i+Mp[i]]==Ma[i − Mp[i]])Mp[i]++;
if(i+Mp[i]>mx)
{
mx=i+Mp[i];
id=i;
}
}
}
/*
* abaaba
* i:
0 1 2 3 4 5 6 7 8 9 10 11 12 13
* Ma[i]: $ # a # b # a # a # b # a #
* Mp[i]: 1 1 2 1 4 1 2 7 2 1 4 1 2 1
*/
char s[MAXN];
int main()
{
while(scanf("%s",s)==1)
{
int len=strlen(s);
Manacher(s,len);
int ans=0;
for(int i=0; i<2*len+2; i++)
ans=max(ans,Mp[i] − 1);
printf("%d\n",ans);
}
return 0;
}
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <set>
#define MAX 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int MAXN=1e4+10;
priority_queue <int,vector<int>,greater<int> > q;
char Ma[MAXN*2];
int Mp[MAXN*2];
void Manacher(char s[],int len)
{
int l=0;
Ma[l++]='$';
Ma[l++]='#';
for(int i=0; i<len; i++)
{
Ma[l++]=s[i];
Ma[l++]='#';
}
Ma[l]=0;
int mx=0,id=0;
for(int i=0; i<l; i++)
{
Mp[i]=mx>i?min(Mp[2*id - i],mx - i):1;
while(Ma[i+Mp[i]]==Ma[i - Mp[i]])Mp[i]++;
if(i+Mp[i]>mx)
{
mx=i+Mp[i];
id=i;
}
}
}
int main()
{
char s[MAXN],ss[MAXN];
cin>>s;
int len=strlen(s);
for(int i=0;i<len;i++)
ss[i]=s[i];
int maxx=-1;
for(int k=0;k<len;k++)
{
//cout<<ss<<endl;
memset(Mp,0,sizeof(Mp));
memset(Ma,0,sizeof(Ma));
Manacher(ss,len);
int ans=0;
for(int i=0; i<2*len+2; i++)
ans=max(ans,Mp[i] - 1);
//cout<<ss<<endl;
// cout<<ans<<endl;
if(ans>=maxx)
maxx=ans;
char c=ss[0];
for(int i=1;i<len;i++)
ss[i-1]=ss[i];
ss[len-1]=c;
}
cout<<maxx<<endl;
return 0;
}