青蛙过河:贪心+二分高效解法,Upgrade Win11 subsystem Ubuntu22.04 to ubuntu24.04。

张开发
2026/4/7 8:04:56 15 分钟阅读

分享文章

青蛙过河:贪心+二分高效解法,Upgrade Win11 subsystem Ubuntu22.04 to ubuntu24.04。
题目概述P8775 [蓝桥杯 2022 省 A] 青蛙过河问题描述如下青蛙需要从河的一侧跳到另一侧河中有若干石头排成一行。青蛙每次跳跃必须落在石头上且跳跃距离不能超过其当前能力值 ( x )。目标是找到最小的 ( x )使得青蛙能在若干次跳跃后过河。问题分析该问题可以分解为两个关键点贪心策略在给定 ( x ) 的情况下判断青蛙是否能过河。二分查找通过二分法高效地搜索最小的 ( x )。贪心策略验证对于固定的 ( x )判断青蛙是否能过河的贪心算法步骤如下初始化当前位置为起点石头 0。每次跳跃到最远的、不超过 ( x ) 距离的石头。若最终能到达终点石头则 ( x ) 可行。贪心的正确性基于局部最优选择能导向全局最优解。二分查找优化直接枚举所有可能的 ( x ) 效率过低。二分查找适用于问题具有单调性若 ( x ) 可行则所有更大的 ( x ) 也可行。搜索范围为 ( 1 ) 到最大石头间距。二分查找的框架如下初始化左边界 ( left 1 )右边界 ( right \text{最大间距} )。每次取中间值 ( mid )用贪心验证 ( mid ) 是否可行。根据验证结果调整左右边界直到找到最小可行 ( x )。代码实现#include iostream #include vector using namespace std; bool canCross(const vectorint stones, int x) { int pos 0; for (int i 0; i stones.size(); ) { int next i; while (next stones.size() stones[next] - stones[i] x) { next; } if (next i) return false; // 无法跳跃 i next - 1; if (i stones.size() - 1) return true; } return false; } int minJumpDistance(vectorint stones) { int left 1; int right stones.back() - stones[0]; int result right; while (left right) { int mid left (right - left) / 2; if (canCross(stones, mid)) { result mid; right mid - 1; } else { left mid 1; } } return result; } int main() { int n; cin n; vectorint stones(n); for (int i 0; i n; i) { cin stones[i]; } cout minJumpDistance(stones) endl; return 0; }复杂度分析贪心验证每次验证时间复杂度为 ( O(n) )其中 ( n ) 为石头数量。二分查找最多进行 ( O(\log(\text{最大间距})) ) 次验证。总复杂度( O(n \log(\text{最大间距})) )高效且适用于大规模数据。关键点总结贪心验证通过局部最优选择快速判断可行性。二分搜索利用单调性减少搜索次数。边界处理注意跳跃失败和终点判断的逻辑。通过结合贪心与二分该算法在保证正确性的同时显著提升了效率。https://raw.githubusercontent.com/noisy-chard-59/24w_rfmw/main/README.mdhttps://github.com/artful-46-doses/rfe_997jhttps://github.com/artful-46-doses/rfe_997j/blob/main/README.mdhttps://raw.githubusercontent.com/artful-46-doses/rfe_997j/main/README.mdhttps://github.com/trig95-marimba/35h_1qwa

更多文章