hdu4004- The Frog's Games(二分答案)

题目链接
题意:
有只青蛙要跳过一条长L的河,其间有n块石头,最多可以跳m次,途中可以借助石头跳到对岸,也可以直接跳到对岸,给出石头距岸边的距离,青蛙每次跳都有一个跳跃距离,跳跃距离必须等于当前位置距要跳的石头或者是对岸的距离才能跳到那个位置,问青蛙在所有可行方案(能跳到对岸,且满足上述条件)中跳的最远的距离至少为多少。

条件:1<=L <= 1000000000,0<= n <= 500000,1<= m <= n+1

分析:
因为n为5*1e5,限时一秒,所以O(n^2)不适用,即纯模拟是无法通过的,而这题也是入门二分题,复杂度O(nlogn)。二分的的l和r,表示当前方案下最远可跳的距离的范围,边界条件需注意,若去除跳跃次数这一约束条件(即可无限次跳),青蛙能跳到对岸,至少需要可跳的最远距离就是相邻石头(还包括石头与岸边)距离中的最大距离,这就确定了l,还有r最多就是L(当n=0)。解法也是看了discuss里大佬的,巧妙之处在于在d数组前面加了起初离岸边0距离,和最后对岸距岸边L距离,这样便于check里判断满足当前假定条件的可跳到的最长距离,还有设置青蛙当前位置标记。最后比较跳跃次数即可。由于数据过大,需要scanf读入,还需注意二分写法。

主要代码

int L,n,m;
bool check(vector<int>& d,int dis){
	int ans=0,pos=0;
	for(int i=1;i<=n;i++){
		if(d[i]-d[pos]<=dis&&d[i+1]-d[pos]>dis){
			ans++;
			pos=i;
		}
	}
	ans++;
	return ans<=m;
}
void solve(){
	vector<int> d(n+2);
	for(int i=1;i<=n;i++){
	scanf("%d",&d[i]);
	}
	d[n+1]=L;
	sort(d.begin(),d.end());
	int max1=0;
	for(int i=1;i<=n+1;i++)
	max1=max(max1,d[i]-d[i-1]);//求l
	int l=max1,r=L;
	while(l<r){
		ll mid=(l+r)>>1;
		if(check(d,mid))
		r=mid;//左区间
		else
		l=mid+1;//右区间
	}
	printf("%d\n",l);
}
int main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0);
	while(~scanf("%d%d%d",&L,&n,&m))
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值