【每日一题】9月29日Stressful Training,最小堆,二分,贪心

Stressful Training

https://ac.nowcoder.com/acm/problem/113525

题目描述

第一行输入共有N个同学,带了N个笔记本,N < 2e5 + 1,需要坚持 K 分钟。
第二行给出N个整数,每个整数代表笔记本初始电量,a[i] < 1e12 + 1
第三行给出N个整数,每个整数代表笔记本每分钟消好电量,b[i] < 1e7 + 1
现在你可以买一个充电器,再每分钟给某个笔记本充电 x 的电量,这个 x 最小是多少?如果永远无法满足那就输出 -1

Solution

稍微思考,可以发现这个答案 x 满足二分的性质,如果当前x可以,我是不是能买小一点的充电器呢?如果不行的就只能吧 x 变大了,所以可以二分这个答案去验证是否可以实现。
那么问题来到如何验证当前 x 是否可以使得全部机子活过 K 分钟。
那么每分钟充电一定是选坚持轮数最小的那一台机器,那么我们使用一个最小堆,把全部的需要充电才能活下来的机器放在最小堆里面去,最小堆的排序规则就是 越早死的排在越前面充电。
这个时候可以特判一下,如果堆中没有元素说明全部机子都可以活下来,不需要充电器,也就是当前 mid 可成立
在接下来枚举 k 分钟,每分钟选最小的机子充电,如果当前选出来的机器活不下来,那就是当前的充电器不合格。
再把充电之后的这个机器算一次可以活下多久,如果活不到 K 分钟就再塞进堆中,
循环 k 次过程中堆中再次没有元素了就还是 return true
完成 K 次循环也是返回 true

#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define all(__vv__) (__vv__).begin(), (__vv__).end()
#define endl "\n"
#define pai pair<ll, pair<ll, ll> >
#define ms(__x__,__val__) memset(__x__, __val__, sizeof(__x__))
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(ll x, int op = 10) { if (!x) { putchar('0'); if (op)    putchar(op); return; }    char F[40]; ll tmp = x > 0 ? x : -x;    if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]);    if (op)    putchar(op); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }    ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
inline int lowbit(int x) { return x & (-x); }
const int dir[][2] = { {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;

const int N = 2e5 + 7;
ll n, k, a[N], b[N];

bool check(ll x) {
    priority_queue<pai, vector<pai>, greater<pai>> pq;
    for (int i = 1; i <= n; ++i)
        if (a[i] / b[i] < k)
            pq.push({ a[i] / b[i],{a[i],b[i]} });
    if (pq.empty())    return true;
    for (int i = 0; i < k; ++i) {
        ll C = pq.top().first, A = pq.top().second.first, B = pq.top().second.second;    pq.pop();
        if (C < i)    return false;
        if (A / B < k) {
            A += x;
            pq.push({ A / B,{A,B} });
        }
        if (pq.empty())    return true;
    }
    return true;
}

int main() {
    n = read(), k = read();
    for (int i = 1; i <= n; ++i)
        a[i] = read();
    for (int i = 1; i <= n; ++i)
        b[i] = read();
    ll l = 0, r = 1e13, ans = -1;
    while (l <= r) {
        ll mid = l + r >> 1;
        if (check(mid))
            ans = mid, r = mid - 1;
        else
            l = mid + 1;
    }
    print(ans);
    return 0;
}
每日一题 文章被收录于专栏

每日一题

全部评论

相关推荐

上周组里招人,我面了六个候选人,回来跟同事吃饭的时候聊起一个让我挺感慨的现象。前三个候选人,算法题写得都不错。第一道二分查找,五分钟之内给出解法,边界条件也处理得干净。第二道动态规划,状态转移方程写对了,空间复杂度也优化了一版。我翻他们的简历,力扣刷题量都在300以上。后三个呢,就有点参差不齐了。有的边界条件没处理好,有的直接说这道题没刷过能不能换个思路讲讲。其中有一个女生,我印象特别深——她拿到题之后没有马上写,而是先问我:“面试官,我能先跟你确认一下我对题目的理解吗?”然后她把自己的思路讲了一遍,虽然最后代码写得不是最优解,但整个沟通过程非常顺畅。这个女生的代码不是最优的,但当我问她“如果这里是线上环境,你会怎么设计’的时候,她给我讲了一套完整的方案——异常怎么处理、日志怎么打、怎么平滑发布。她对这是之前在实习的时候踩过的坑。”我在想LeetCode到底在筛选什么?我自己的经历可能有点代表性。我当年校招的时候,也是刷了三百多道题才敢去面试。那时候大家都刷,你不刷就过不了笔试关。后来工作了,前三年基本没再打开过力扣。真正干活的时候,没人让你写反转链表,也没人让你手撕红黑树。更多的是:这个接口为什么慢了、那个服务为什么OOM了、线上数据对不上了得排查一下。所以后来我当面试官,慢慢调整了自己的评判标准。算法题我还会出,但目的变了。我出算法题,不是想看你能不能背出最优解。而是想看你拿到一个陌生问题的时候,是怎么思考的。你会先理清题意吗?你会主动问边界条件吗?你想不出来的时候会怎么办?你写出来的代码,变量命名乱不乱、结构清不清楚?这些才是工作中真正用得到的能力。LeetCode是一个工具,不是目的。它帮你熟悉数据结构和常见算法思路,这没问题。但如果你刷了三百道题,却说不清楚自己的项目解决了什么问题、遇到了什么困难、你是怎么解决的,那这三百道题可能真的白刷了。所以还要不要刷LeetCode?要刷,但别只刷题。刷题的时候,多问自己几个为什么:为什么用这个数据结构?为什么这个解法比那个好?如果换个条件,解法还成立吗?把刷题当成锻炼思维的方式,而不是背答案的任务。毕竟面试官想看到的,从来不是一台背题机器,而是一个能解决问题的人。
牛客51274894...:意思是光刷力扣还不够卷
AI时代还有必要刷lee...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务