跳石头

在这里插入图片描述
二分思路:这是一道典型的二分答案的题目,题目中要求的:求最短跳跃距离的最大值,就是典型二分答案,题目已经给出了二分答案的两个条件:单调性和有界性,单调性就是石头之间的距离是单调递增的,并且给出了他们的起点与终点,我们可以在这一段距离内进行二分答案,然后在check函数中判断我们每次跳跃的距离,假设我们现在二分的答案是正确答案,如果前后两个石头的距离小于我们二分的答案,那么我们就要将他移除,否则就可以跳过这一块石头,最后我们在判断一下移除的石头是不是大于了输入的最大移除数:
如果是的话,返回false,因为我们的这个二分答案开大了,所以会导致很多石头都符合移除的条件,我们将右边界赋值为mid-1,
否则如果移除的石头小于等于我们二分出来的答案,那么这个答案可能就是当前的最优解,因为它没有超过最大的移除数,然后我们再在它的右边继续寻找最短跳跃距离的最大值
(最短跳跃距离的最大值):就是我们在不超过最大移除数的情况下,所能二分到的最短最大跳跃距离,超过这个距离,我们移除的石头就会超过输入的最大值

上代码

#include<bits/stdc++.h>
using namespace std;
int d,n,m,mid,ans,l,r;
int a[55555];

bool check(int x){
	int tot=0,now=0;
	for(int i=1;i<=n;i++){
		if(a[i]-a[now]<x)tot++; //如果小于我们二分的答案,我们就移走他 
		else now=i;
	}
	if(tot>m) return false;
	else return true;
	//如果移走的石头大于我们的最大移除数,那么它和他右边的所有数都是非法的
	//否则它就是当前的最优解,并且我们在它的右边继续寻找更大的解
}
int main(){
	cin>>d>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	a[n+1]=d;
	l=1,r=d;
	while(l<=r){
		mid=(l+r)>>1;
		if(check(mid))l=(ans=mid)+1; //当前的数是最优解,并且在它的右边去寻找更优解
		else r=mid-1; //它右边的都是非法解,我们直接将边界拉到mid-1的位置寻找更小的解
	}
	cout<<ans; //输出答案
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这咋又bug了嘛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值