B-嬲 NAMOMO OJ contest 3

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;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/107438308