HZOI20190810 T1

A:blue(青蛙乱跳)

好像很多人都是用的队列?甚至还有用set

然而。。。博主太蒻了,只能找一个sb的规律

我们来手模一个样例:

10 9 16 30
2 4 6 9 11 15 18 19 25 27 

他的答案是5。

我们思考5是如何出来的

我们画一个坐标,从0开始,那么由0最远跳到位于15的石头,从0到15(不包括左端点但包括右端点)共有6个石子

对于下一个石头2,它最远跳到18,共有6个石子,

同理,4有6个,6有5个。。。。

那么如果我们不算上最后几个重复的最远到30的,那么最小就是5

对于其他样例同样适用,对于一个a[i],upper_bound找出小于等于a[i]+d的位置p,

更新ans=min(ans,p-i),注意边界!不要重复算上最后的几个,因为27到30有1个石子,但显然不是答案,25也不是

然后。。。这个思路竟然A了!!!!蛤蛤蛤蛤蛤

我先置顶,有那位大佬来hack一下?或者帮我解释一下为什么正确,多谢

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=1e6+5;
int T,n,m,d,l,a[MAXN],ans;
signed main(){
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld%lld",&n,&m,&d,&l);
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		ans=m;
		for(int i=0;i<=n&&a[i]<l-d;i++){
			int p=upper_bound(a+i,a+n+1,a[i]+d)-a-1;
			ans=min(ans,p-i);
		}
		if(ans==m) puts("Excited");
		else printf("%lld
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Juve/p/11331996.html