蓝桥杯——最大通过数

前缀和 + 二分答案

        因为通过的关卡数量与消耗的能量成正相关,所以使用二分答案来降低时间复杂度。

        而本题求最大通过数时,不可以简单的用贪心直接比较两个数组中当前下标谁更小,否则会出现反例,比如a:1  888 888 888,b: 999 1 1 1,如果简单的贪心,那这个例子就会一直在a数组中选择关卡,但是实际上选b数组会更好。

        所以无法通过当前关卡的大小来判断究竟是选择a数组还是b数组,就像之前最大数组和那道题目一样,但他们都有一个共同点,就是求的都是一段连续区间的和,所以使用前缀和对所有情况进行一一枚举,找到在当前给出的通过关卡数量的前提下,需要的最小能量。

        如果这个最小能量小于等于题目给出的能量,那就增加假定的通过的关卡数量,直到找出最大的通过关卡数量。

                          

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 9;
ll a[maxn];
ll b[maxn];

bool check(int x, int n, int m, ll k) {
    ll num = 1e10;
    int j = 0;
    for (int i = 0; i <= n; i++) {
        j = x - i;
        if (j < 0) break;
        if (j > m) continue;
        else num = min(num, a[i] + b[j]);
    }

    if (num > k) return true;
    else return false;
}

int main()
{
    int n, m;
    ll k; cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        a[i] += a[i - 1];
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
        b[i] += b[i - 1];
    }

    int l = 0, r = m + n + 1;
    while (l + 1 < r) {
        int mid = (l + r) / 2;
        if (check(mid, n, m, k)) r = mid;
        else l = mid;
    }

    cout << l;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值