2026: 青蛙过河(New Online Judge)

2026: 青蛙过河(New Online Judge)

题目描述

小青蛙住在一条河边,它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。河里的石头排成了一条直线,小青蛙每次跳跃必须落在一块石头或者岸上。
不过,每块石头有一个高度,每次小青蛙从一块石头起跳,这块石头的高度就会下降1。当石头的高度下降到0 时小青蛙不能再跳到这块石头上(某次跳跃后使石头高度下降到0 是允许的)。小青蛙一共需要去学校上x 天课,所以它需要往返2x 次。当小青蛙具有一个跳跃能力y 时,它能跳不超过y 的距离。
请问小青蛙的跳跃能力至少是多少才能用这些石头上完x 次课。

输入

输入的第一行包含两个整数n, x,分别表示河的宽度和小青蛙需要去学校的天数。
请注意2x 才是实际过河的次数。
第二行包含n - 1 个非负整数H1, H2, … , Hn-1。
其中Hi > 0 表示在河中与小青蛙的家相距i 的地方有一块高度为Hi 的石头,Hi = 0 表示这个位置没有石头。
30%的测试数据:n≤100
60%的测试数据:n≤1000
100%的测试数据: 1 ≤ n ≤ 100000 , 1 ≤ x ≤ 1 0 9 , 0 ≤ H i ≤ 1 0 4 1≤n≤100000,1≤x≤10^9,0≤Hi≤10^4 1n1000001x1090Hi104

输出

输出一行,包含一个整数,表示小青蛙需要的最低跳跃能力。

样例输入

5 1
1 0 1 0

样例输出

4

提示信息

由于只有两块高度为1 的石头,所以往返只能各用一块。
第1 块石头和对岸的距离为4,如果小青蛙的跳跃能力为3 则无法满足要求。
所以小青蛙最少需要4 的跳跃能力。

题解1(C++版本)

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;

int n, m, h[N], pre[N]; 
// 记当前二分的跳跃能力为mid,若所有长度为mid的区间的和都>=2x,则可行,否则不可行,使用前缀和的思想来判断
bool check(int x){
	for(int i = 1; i + x - 1 <= n; i++){
		if(pre[i + x - 1] - pre[i - 1] < 2*m) return false;
	}
	return true;
}

// 正向跳跃与反向跳跃的效果是一样的,因此,本题可以简化成正向跳跃2x次 
signed main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i < n; i++) scanf("%d", &h[i]), pre[i] = pre[i - 1] + h[i];
	pre[n] = 1e9; //终点的高度设置为很大
	int L = 0, R = n + 1, mid;
	while(L + 1 < R){
		mid = (L + R)/2;
		if(check(mid)) R = mid;
		else L = mid;
	}
	printf("%d\n", R);
	return 0;
}
  • 40
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值