有些地方需要解释:
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]; // 跳到下一个石头或河岸上}// 如果小青蛙无法跳到河的对岸,返回0if(now < all)return 0;// 继续模拟小青蛙的跳跃,判断是否能成功到达河的对岸for(int i = x; i < n; i++) {now += arr[i]; // 跳到下一个石头或河岸上now -= arr[i - x]; // 减去前一个石头的高度,保持距离为xif(now < all) // 如果无法成功到达河的对岸,返回0return 0;}// 能够成功到达河的对岸,返回1return 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;} elseleft = mid + 1;}// 输出最低跳跃能力cout << ans;return 0;
}