https://namomo.top:8081/contest/3/problem/B
k=1 , 单个点连跳,k=2,相邻反复横跳。剩下的就找最大团也就是可以循环跳的最大区间,长度大于等于2的就可以拓展,最大团>=k就也是随便跳。如果不能随便跳,就找最长的链输出长度。
比赛的时候在代码里下毒WA了,然后全队3个人赛后对着这份代码思考了一年,1点半找到错误了。。。每次跳跃时,i=r,而不能直接i=r+1,因为可能是i-1到i只能拓展距离为1,而i可以拓展到i+2
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
ll n,m,cas,k,cnt,tot,ans,mx;
ll b[maxl];
ll x;
ll a[maxl];
char s[maxl];
inline void prework()
{
scanf("%lld%lld%lld",&n,&x,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]),b[i]=0;
b[0]=b[n+1]=0;
ans=0;
if(k==1)
{
ans=-1;
return;
}
for(ll i=1;i<=n;i++)
{
b[i]=max(b[i-1],i);
while(b[i]+1<=n && a[b[i]+1]-a[i]<=x)
b[i]++;
if(k==2 && b[i]>i)
{
ans=-1;
return;
}
}
mx=0;ll r;
for(ll i=1;i<=n;)
{
r=i;
for(ll j=i;j<=r;j++)
if(b[j]-j>=2)
r=max(r,b[j]);
else
break;
mx=max(mx,r-i+1);
if(i==r) i++;
else i=r;
}
if(mx>=k)
ans=-1;
}
inline void mainwork()
{
if(ans<0)
return;
ll l=1,r=1;ans=0;
while(l<=n)
{
r=l;
while(r+1<=n && b[r]>r)
r++;
ans=max(ans,r-l+1);
l=r+1;
}
}
inline void print()
{
if(ans<0)
puts("niao!");
else
printf("%lld\n",ans);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}