题目链接:点我
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 100009
int t[N<<1],p[N<<1];
int manacher(int n)
{
int i,id=0,mx=0,ans=0;
for(i=1; i<=n; i++)
{
if(mx>i) p[i]=min(mx-i,p[2*id-i]);
else p[i]=1;
while(t[i+p[i]]==t[i-p[i]]&&t[i-p[i]]<=t[i-p[i]+2]) p[i]++;//就在这一处地方加了条件判断。
if(mx<i+p[i])
mx=i+p[i],id=i;
ans=max(ans,p[i]);
}
return ans-1;
}
int main()
{
int tt,n,i;
cin>>tt;
while(tt--)
{
cin>>n;
t[0]=-1,t[1]=0;
for(i=1; i<=n; i++)
{
scanf("%d",&t[2*i]);
t[2*i+1]=0;
}
printf("%d\n",manacher(2*n+1));
}
}
需要注意的是此题前半部分回文串是不降低排列,所以t[0]要比插入的元素(t[1],t[3],t[5],,,)要小
如果是 0,-1,51,-1,52,-1,51,-1那么就会出现t[0]也会匹配的现象,所以要让t[0]最小
写法2:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 100009
int t[N];
int main()
{
int tt,n,i;
cin>>tt;
while(tt--)
{
cin>>n;
t[0]=-1;//如果不写这句会默认t[0]=0,一直前后延伸下去
for(i=1; i<=n; i++)
{
scanf("%d",&t[i]);
}
int s,e,ans=0;
for(i=1; i<=n; i++)
{
s=i,e=i;
while(t[s]==t[e+1])e++;
i=e;
while(t[s-1]==t[e+1]&&t[s-1]<=t[s]) s--,e++;
ans=max(ans,e-s+1);
}
printf("%d\n",ans);
}
return 0;
}