首页 数字经济

C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解

分类:数字经济
字数: (3356)
阅读: (7450)
内容摘要:C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解,

在蓝桥杯竞赛中,P8775 青蛙过河这道题是一道经典的运用C++贪心算法结合二分查找思想解决的问题。很多选手可能第一时间想到动态规划,但是动态规划的时间复杂度相对较高,在数据量较大的情况下容易超时。本文将从问题场景、原理、代码实现以及实战经验等方面,深入剖析如何利用贪心和二分查找高效解决此问题。

问题场景重现

题目描述:

有一条河,宽度为 W。河中有 N 块石头,每块石头距离河岸的距离为 Di,青蛙最多能跳跃的距离为 L。现在需要求出青蛙跳过河需要踩到的最少石头数量,如果无法跳过河,则输出-1。

C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解

数据范围:

  • 1 <= N <= 10^5
  • 1 <= W <= 10^9
  • 1 <= L <= 10^9
  • 1 <= Di <= W

输入样例:

C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解
10 3 5
1 2 8

输出样例:

2

底层原理深度剖析

贪心策略

本题的核心在于如何选择石头,才能使得跳跃次数最少。一个显而易见的贪心策略是:每次都尽可能跳远,选择当前能够到达的最远的石头。这个策略背后的逻辑是,如果当前能够到达更远的石头,那么必然比只到达近处的石头更有利,因为这减少了后续跳跃的次数。这与Nginx反向代理中,选择延迟最低的服务器进行请求转发的原理类似,都是为了追求当下最优。

C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解

二分查找

为了快速找到当前能够到达的最远的石头,我们可以使用二分查找。首先将石头按照距离河岸的距离进行排序。每次跳跃时,利用二分查找找到距离当前位置不超过L的最远石头。二分查找的效率是O(logN),相对于线性查找,大大提高了算法的效率。

这里与我们平时配置Nginx负载均衡时,使用upstream模块进行服务器健康检查,并在发生故障时快速切换到其他可用服务器的思路是一致的,都是为了保证服务的稳定性和可用性。

C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解

具体的代码/配置解决方案

以下是 C++ 代码实现,代码中包含了详细的注释。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    int W, N, L;
    cin >> W >> N >> L;

    vector<int> stones(N);
    for (int i = 0; i < N; ++i) {
        cin >> stones[i];
    }

    sort(stones.begin(), stones.end()); // 将石头按照距离排序

    int current_position = 0; // 青蛙当前位置
    int count = 0; // 跳跃次数
    int i = 0; //stones数组下标

    while (current_position < W) {
        int next_stone_index = -1;
        // 找到当前位置可以到达的最远石头
        while(i < N && stones[i] <= current_position + L){
            next_stone_index = i;
            i++;
        }
        if (next_stone_index == -1) { // 如果没有石头可以到达
             if(current_position + L >= W){
                cout << count << endl;
                return 0;
             }else{
               cout << -1 << endl;
               return 0;
             }
        }

        current_position = stones[next_stone_index]; // 跳到最远石头
        count++; // 跳跃次数加一
    }

    cout << count << endl;

    return 0;
}

实战避坑经验总结

  1. 排序:一定要对石头的位置进行排序,这是二分查找的基础。
  2. 边界条件:注意处理边界条件,例如没有石头可以到达的情况,以及已经到达终点的情况。
  3. 数据类型:题目中 W 和 L 的范围较大,需要使用 int 类型存储,防止溢出。
  4. 贪心策略证明:虽然贪心策略在这个问题中是正确的,但是在其他问题中,贪心策略不一定总是能够得到最优解。因此,在应用贪心算法时,需要仔细分析问题,证明贪心策略的正确性。
  5. Nginx的类比思考:将青蛙跳跃问题类比于Nginx服务器选择,有助于理解贪心算法的本质,即在每一步都选择当前最优的策略,最终达到全局最优。例如,在高并发场景下,Nginx通过连接池技术,复用已建立的连接,避免频繁创建和销毁连接的开销,这也是一种贪心策略,旨在减少资源消耗,提高系统性能。

总结,通过C++贪心策略结合二分查找,我们能够高效地解决蓝桥杯青蛙过河问题。在实际应用中,我们需要灵活运用各种算法思想,结合具体的场景,选择最合适的解决方案。

C++ 贪心与二分:蓝桥杯青蛙过河问题高效求解

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea2.store/blog/309603.SHTML

本文最后 发布于2026-04-07 21:56:01,已经过了20天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 臭豆腐爱好者 4 天前
    这题贪心+二分确实是正解,一开始我用DP做的,直接超时了,感谢大佬指点!
  • 榴莲控 3 天前
    这个贪心策略的证明感觉还可以再深入一些,有没有更严谨的数学推导?
  • 咸鱼翻身 6 天前
    大佬,请问如果石头位置不是整数,而是浮点数呢?代码需要怎么修改?
  • 薄荷味的夏天 4 小时前
    大佬,请问如果石头位置不是整数,而是浮点数呢?代码需要怎么修改?