当前位置:首页 > 蓝桥杯 > 洛谷P10909题(2024蓝桥杯国B):二分查找+贪心算法解决立定跳远

洛谷P10909题(2024蓝桥杯国B):二分查找+贪心算法解决立定跳远

2个月前 (08-15)

洛谷P10909题(2024蓝桥杯国B):二分查找+贪心算法解决立定跳远 洛谷题解 二分查找 贪心算法 蓝桥杯 国赛 第1张

一、题目解读

洛谷P10909是一道典型的贪心策略问题,要求在一个递增数列中,通过跳跃到达终点,并允许使用一次“爆发技能”以扩大单次跳跃距离。题目核心在于如何在限定跳跃次数内,合理分配普通跳跃与技能使用,找到最优的最大跳跃距离。

二、解题思路

1. 核心思想:采用二分查找确定最大可行跳跃距离。由于跳跃次数与距离呈反比关系,可通过二分法缩小解的范围。

2. 贪心优化:引入“爆发技能”的两种使用场景——中途遇长距离时使用,或末尾补用(若未使用过)。通过检查函数判断当前距离是否满足条件,并优先利用技能减少总次数。

三、解题步骤

1. 输入处理:读取n(元素数量)、m(最大跳跃次数)及数列a。

2. 特殊情况:n=1时直接输出(a[0]+1)/2,避免二分退化。

3. 二分查找区间:left=1,right=末尾元素值,通过mid=(left+right)/2迭代

4. 检查函数逻辑:

○ 遍历数列,计算相邻距离dist。

○ 若use_boost且未使用技能,且dist>mid但≤2*mid,则触发技能并更新位置。

○ 若dist>mid,按普通规则累加跳跃次数(cnt)。

○ 末尾检查:若技能未用且末尾距离符合条件,补用技能。

5. 二分终止条件:找到满足check(mid, m, false)或check(mid, m, true)的最大mid值。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool check(long long L, const vector<int>& a, int m, bool use_boost) {
    int cnt = 0;
    long long prev = 0;
    bool boost_used = false;
    
    for (int i = 0; i < a.size(); ++i) {
        long long dist = a[i] - prev;
        if (use_boost && !boost_used && dist > L) {
            // 尝试在此处使用爆发技能
            if (dist <= 2 * L) {
                boost_used = true;
                prev = a[i];
                continue;
            }
        }
        
        if (dist > L) {
            cnt += (dist - 1) / L;
            if (cnt > m) return false;
        }
        prev = a[i];
    }
    
    // 如果使用爆发技能但没用上,尝试在最后使用
    if (use_boost && !boost_used) {
        long long last_dist = a.back() - (a.size() > 1 ? a[a.size()-2] : 0);
        if (last_dist > L && last_dist <= 2 * L) {
            boost_used = true;
        }
    }
    
    return cnt <= m && (!use_boost || boost_used);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    
    // 处理特殊情况:n=1时只需要跳一次
    if (n == 1) {
        cout << (a[0] + 1) / 2 << endl;
        return 0;
    }
    
    long long left = 1, right = a.back(), ans = a.back();
    while (left <= right) {
        long long mid = (left + right) / 2;
        if (check(mid, a, m, false) || check(mid, a, m, true)) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    
    cout << ans << endl;
    return 0;
}

五、总结

本解法通过二分查找高效定位最优跳跃距离,结合贪心策略灵活处理爆发技能的使用时机,兼顾了时间与空间效率。关键在于将跳跃次数转化为距离约束,并利用技能的双条件检查实现全局优化。该思路适用于类似需要动态平衡资源分配的问题。


原创内容 转载请注明出处

分享给朋友:

相关文章

征服力扣704题:三步掌握经典二分查找算法

征服力扣704题:三步掌握经典二分查找算法

题目重解我们面对的是算法领域最经典的二分查找问题:在一个已排序的整数数组中,快速定位目标值的位置。就像在一本按字母顺序排列的字典中查找单词,我们不需要逐页翻阅,而是通过不断折半的方式快速缩小搜索范围,...

洛谷P1007士兵过桥问题详解 C++贪心算法实现与优化

洛谷P1007士兵过桥问题详解 C++贪心算法实现与优化

题目解读这道题目描述了一座长度为L的桥上有n个士兵,每个士兵每秒可以向左或向右移动1个单位。当士兵到达桥的端点(0或L+1)时离开桥。要求计算所有士兵离开桥的最小时和最大时间。解题思路最小时计算:每个...

牛客13271题「删除K个数字的最小数」解题报告:贪心算法与栈的应用(附代码注释)

牛客13271题「删除K个数字的最小数」解题报告:贪心算法与栈的应用(附代码注释)

一、题目解读牛客13271题要求从给定的数字字符串中删除K个数字,使得剩余数字按原顺序排列后得到的最小数。题目核心在于如何在保持数字相对顺序的前提下,通过删除操作得到最优解。需注意结果字符串可能包含前...

【牛客13256题解析】贪心算法优化题目组合问题:三元组与二元组的解题思路

【牛客13256题解析】贪心算法优化题目组合问题:三元组与二元组的解题思路

一、题目解读牛客13256题要求处理一组题目难度数据,通过组合三元组(难度差≤20)或二元组(难度差≤10)来重新编排题目,计算需要补充的最小题目数量。题目本质是资源分配与优化问题,需高效组合现有题目...

2024蓝桥杯国赛B组最小字符串题解:贪心算法实战应用(洛谷P10910代码解析)

2024蓝桥杯国赛B组最小字符串题解:贪心算法实战应用(洛谷P10910代码解析)

一、题目解读题目要求给定一个长度为N的字符串S和M个待插入字符,通过将这些字符全部插入S中,构造出字典序最小的新字符串。这是典型的字符串构造问题,考察选手对贪心算法的理解和应用能力。二、解题思路采用贪...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。