二分答案+贪心+longlong快读

Stressful Training

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

Stressful Training

题目描述:

Berland SU holds yet another training contest for its students today. nnn students came, each of them brought his laptop. However, it turned out that everyone has forgot their chargers!

Let students be numbered from 111 to nnn. Laptop of the iii-th student has charge aia_iai at the beginning of the contest and it uses bib_ibi of charge per minute (i.e. if the laptop has ccc charge at the beginning of some minute, it becomes c−bic - b_ic−bi charge at the beginning of the next minute). The whole contest lasts for kkk minutes.

Polycarp (the coach of Berland SU) decided to buy a single charger so that all the students would be able to successfully finish the contest. He buys the charger at the same moment the contest starts.

Polycarp can choose to buy the charger with any non-negative (zero or positive) integer power output. The power output is chosen before the purchase, it can't be changed afterwards. Let the chosen power output be xxx. At the beginning of each minute (from the minute contest starts to the last minute of the contest) he can plug the charger into any of the student's laptops and use it for some integer number of minutes. If the laptop is using bib_ibi charge per minute then it will become bi−xb_i - xbi−x per minute while the charger is plugged in. Negative power usage rate means that the laptop's charge is increasing. The charge of any laptop isn't limited, it can become infinitely large. The charger can be plugged in no more than one laptop at the same time.

The student successfully finishes the contest if the charge of his laptop never is below zero at the beginning of some minute (from the minute contest starts to the last minute of the contest, zero charge is allowed). The charge of the laptop of the minute the contest ends doesn't matter.

Help Polycarp to determine the minimal possible power output the charger should have so that all the students are able to successfully finish the contest. Also report if no such charger exists.

题意:

有n台电脑,一共要撑过k分钟
对于每台电脑,他的初始电量为ai,每分钟消耗电量为bi
问,至少需要一个功率(每分钟)为多大的充电器才能保证[0,k)时间内每一台电脑的电量都不为负

思路:

最大功率的最小值,很显然是二分

但是这个题的check函数极其不好写(╥﹏╥)

首先到底给哪个充电?这就是一个贪心,每次都找能坚持的时间最小的那个,如果坚持的时间相同,我们就选bi大的那个,如果bi也相同,我们就选ai小的那个

所以就需要用结构体来存每个电脑的ai,bi和ci(也就是ai / bi)

同时要用一个优先队列/小根堆来维护

维护的东西就是上面写的那个贪心,这里就要写结构体重载,不然塞不进优先队列

对于每次check(x)时,先选出来ci < k的放进优先队列q中,判断一下对列是否为空,空就返回true,从0循环到k-1(从0开始是因为可能有电脑一次都撑不住,k-1是因为最后一次即比赛结束时电量为多少就已经不在乎了),取出队首,扔出去,判断一下此时他的ci是否小于i,小于的话就说明它撑不到给他充电的时候(就是两个电脑同时缺电,但却只有一个充电器,无法撑住),就return false,然后将加上x的点亮的点重新放进优先队列,循环往复……

再就是会有-1的存在,也就是没有能满足的充电器,此时的check返回的是false,所以我们就在true的地放更新ans,对于没有充电器的情况,就不会运行到r = mid + 1 , 就不会改ans的值,就只需要初始化ans为-1即可

再就是这个题比较坑的就是,卡输入,不开快读会TLE,再就是输入的数是1e12,所有得开longlong,所以就得用longlong的快读╮( ̄▽ ̄"")╭

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using namespace std;
#define inf 0x3f3f3f3f
#define MAX 1000000 + 50
#define endl '\n'
#define seed 13331
#define mod 1000000007
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(a,b) memset((a),(b),sizeof(a))
typedef  long long ll ;
//不开longlong见祖宗!
//inline __int128 read(){__int128 x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-'){f = -1;}ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;}
//inline void print(__int128 x){if(x < 0){putchar('-');x = -x;}if(x > 9){print(x / 10);}putchar(x % 10 + '0');}
inline ll llRead(){ll x(0), t(1);char o (getchar());while (o < '0' || o > '9') {if (o == '-') {t = -1;}o = getchar();}for (; o >= '0' && o <= '9'; o = getchar()) {x = (x << 1) + (x << 3) + (o ^ 48);}return x * t;}
inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;}
inline void write(int x){if (x < 0) {x = ~x + 1; putchar('-');}if (x > 9){write(x / 10);}putchar(x % 10 + '0');}
ll qpow(ll a,ll n){ll ans=1,base=a%mod;while(n){if(n&1)ans=(ans*base)%mod;base=(base*base)%mod;n>>=1;}return ans;}
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

ll n, k, ans = -1;
struct ran{
    ll a, b, c;
    bool operator < (const ran &X)const{
        if(X.c != c)return c > X.c;
        else if(X.b != b)return b < X.b;
        return a > X.a;
    }
}tr[MAX], now, nextt;

bool check(ll x){
    priority_queue<ran>q;
    for(int i = 1; i <= n; ++i){
        if(tr[i].c < k)q.push(tr[i]);
    }
    if(q.empty())return true;
    for(int i = 0; i < k; ++i){
        now = q.top();q.pop();
        if(now.c < i)return false;
        if((now.a + x) / now.b < k){
            nextt.a = now.a + x;
            nextt.b = now.b;
            nextt.c = nextt.a / nextt.b;
            q.push(nextt);
        }
        if(q.empty())return true;
    }
    return true;
}

int main(){
    n = llRead();k = llRead();
    for(int i = 1; i <= n; ++i)tr[i].a = llRead();
    for(int i = 1; i <= n; ++i){
        tr[i].b = llRead();
        tr[i].c = tr[i].a / tr[i].b;
    }
    ll l = 0, r = 2e12;
    while (l <= r){
        ll mid = (l + r) / 2;
        if(check(mid)){
            ans = mid;
            r = mid - 1;
        }
        else l = mid + 1;
    }
    cout<<ans<<endl;
    return 0;
}
全部评论

相关推荐

最近又搬回宿舍了,在工位坐不住,写一写秋招起伏不断的心态变化,也算对自己心态的一些思考表演式学习从开始为实习准备的时候就特别焦虑,楼主一开始选择的是cpp后端,但是24届这个方向已经炸了,同时自己又因为本科非92且非科班,所以感到机会更加迷茫。在某天晚上用java写出hello&nbsp;world并失眠一整晚后选择老本行干嵌入式。理想是美好的,现实情况是每天忙但又没有实质性进展,总是在配环境,调工具,顺带还要推科研。而这时候才发现自己一直在表演式学习,徘徊在设想如何展开工作的循环里,导致没有实质性进展。现在看来当时如果把精力专注在动手写而不是两只手端着看教程,基本功或许不会那么差。实习的焦虑5月,楼主...
耶比:哲学上有一个问题,玛丽的房间:玛丽知道眼睛识别色彩的原理知道各种颜色,但是她生活在黑白的房间里,直到有一天玛丽的房门打开了她亲眼看到了颜色,才知道什么是色彩。我现在最大可能的减少对非工作事情的思考,如果有一件事困扰了我, 能解决的我就直接做(去哪里或者和谁吵架等等……),解决不了的我就不想了,每一天都是最年轻的一天,珍惜今天吧
投递比亚迪等公司10个岗位 > 秋招被确诊为…… 牛客创作赏金赛
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务