有些地方需要解释:
1.从学校到家和从家到学校,跳跃都是一样的,直接看作2*x次过河就可以。
2.对于一个跳跃能力 y,青蛙能跳过河 2x 次,当且仅当对于每个长度为 y 的区间,这个区间内 h 的和都大于等于 2x。
思路分析:
- 首先定义了一个辅助函数
check
,用于检查是否存在一种跳跃能力满足要求。该函数接受三个参数:跳跃能力x
、石头高度数组arr
和总共需要跳跃的距离all
。 - 主函数开始时,读入河的宽度
n
和小青蛙需要去学校的天数x
,并将x
转换为实际过河的次数。 - 接着读入每块石头的高度,并初始化二分查找的左右边界。
- 使用二分查找来找到最低的跳跃能力,使得小青蛙能够按要求过河。二分查找的左边界为1,右边界为
n-1
。 - 在二分查找的过程中,调用
check
函数检查当前跳跃能力是否满足要求,如果满足则更新最低跳跃能力,并将右边界调整为mid-1
,否则将左边界调整为mid+1
。 - 最终输出最低跳跃能力。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n;//河的长度
// 辅助函数:检查是否存在一种跳跃能力满足要求
int check(int x, int arr[], int all) {
int now = 0; // 初始化小青蛙的位置
// 模拟小青蛙的跳跃过程
for(int i = 0; i < x; i++) {
now += arr[i]; // 跳到下一个石头或河岸上
}
// 如果小青蛙无法跳到河的对岸,返回0
if(now < all)
return 0;
// 继续模拟小青蛙的跳跃,判断是否能成功到达河的对岸
for(int i = x; i < n; i++) {
now += arr[i]; // 跳到下一个石头或河岸上
now -= arr[i - x]; // 减去前一个石头的高度,保持距离为x
if(now < all) // 如果无法成功到达河的对岸,返回0
return 0;
}
// 能够成功到达河的对岸,返回1
return 1;
}
int main() {
int x;
cin >> n >> x; // 读取河的宽度和小青蛙需要去学校的天数
x *= 2; // 实际过河的次数为2倍天数
int arr[n];
for(int i = 0; i < n - 1; i++) // 读取每块石头的高度
cin >> arr[i];
int mid, ans = n;
int left = 1, right = n; // 初始跳跃能力范围为[1, n]
n = n - 1; // 更新河的宽度为石头数量
// 使用二分查找来找到最低的跳跃能力,使得小青蛙能够按要求过河
while(left <= right) {
mid = (left + right) / 2;
if(check(mid, arr, x) == 1) {
ans = mid; // 更新最低跳跃能力
right = mid - 1;
} else
left = mid + 1;
}
// 输出最低跳跃能力
cout << ans;
return 0;
}