题目链接

题目

见链接。

题解

方法一

知识点:贪心,优先队列,二分。

显然,这道题可以用二分答案做。check 函数可以用小根堆,让维持时间最小的先充电。

但是不优化这道题会炸。有两个关键优化:一个是快读快写能省不少时间,还有一个是把维持天数当一个变量存起来以免重复运算浪费时间。其他一些小优化:用 pop 把元素弹出代替析构函数自己初始化能省一点时间,只让天数小于 \(k\) 的电脑入队,每次充完电检测维持天数小于 \(k\) 的才重新入队。优化前是超 \(3\) 秒限制的,优化后是 \(1.5\) 秒还算可以。

时间复杂度 \(O((n+k)\log n)\) ,常数应该在 \((100,1000)\)

空间复杂度 \(O(n)\)

方法二

知识点:贪心,二分。

方法一的检验并非正解,其实有一个更妙的方法去验证电脑是否会在 \(k\) 天之前关机。

我们用一个数组 \(cnt[i]\) 表示有多少电脑最晚第 \(i\) 天前要充一次电。比如一台电脑是初始电量是 \(20\) 每天耗电 \(15\) 要维持到 \(8\) 天,每次充电 \(40\) ,那么它最晚在第 \(2\) 、\(5\)、\(7\) 天要充一次电,于是 \(cnt[\{2,5,7\}]\) 都要加一。

我们不关心电脑在哪天充电,我们只关心电脑最晚要在什么时候前充电,所以 \(cnt[i]\) 在某些天超过 \(1\) 是可行的。因为既然我们知道在这天之后有三台电脑会关机,只要在这天之前什么时候充电都行,不过要满足之前有空闲的天数。

于是,现在我们把它从 \(1\) 到 \(i\) 累和,得到一个结果 \(sum\) ,表示到 \(i\) 天要至少要充几次电,显然每天只能充一次,那么如果 \(sum > i\) ,则存在电脑没在最晚时间前充上电,关机了,是这个答案是不可行的。如果 \(sum \leq i\) ,说明到第 \(i\) 天充电次数完全够用,可以继续。

时间复杂度 \(O(n+k)\) ,常数在 \((50,200)\)

空间复杂度 \(O(n+k)\)

代码

方法一

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. inline ll read() {
  5. ll x = 0, f = 1;
  6. char c = getchar();
  7. while (c < '0' || c>'9') {
  8. if (c == '-') f = -1;
  9. c = getchar();
  10. }///整数符号
  11. while (c >= '0' && c <= '9') {
  12. x = (x << 3) + (x << 1) + (c ^ 48);
  13. c = getchar();
  14. }///挪位加数
  15. return x * f;
  16. }///关键优化,快读
  17. struct node {
  18. ll a, b, v;///关键优化,存储天数
  19. bool operator>(const node &x) const {///大根堆重载小于,小根堆重载大于,true代表优先级小,必须是常函数或者友元函数
  20. return v > x.v;
  21. }
  22. }a[200007];
  23. int n, k;
  24. // struct cmp {
  25. // bool operator()(const node &a, const node &b) {
  26. // return a.a / a.b > b.a / b.b;
  27. // }
  28. // } ///也可以写个比较类
  29. priority_queue<node, vector<node>, greater<node>> pq;
  30. //priority_queue<node, vector<node>, cmp> pq;
  31. bool check(ll mid) {
  32. while (!pq.empty()) pq.pop();///优化
  33. for (int i = 0;i < n;i++) if (a[i].v < k)pq.push(a[i]); ///优化
  34. for (int i = 1;i <= k;i++) {
  35. if (pq.empty()) return true;
  36. node x = pq.top();
  37. pq.pop();
  38. if (x.v < i) return false;///加之前判断是否能撑到这个时候
  39. x.a += mid;
  40. x.v = x.a / x.b + 1;
  41. if (x.v < k) pq.push(x);///优化
  42. }
  43. return true;
  44. }
  45. int main() {
  46. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  47. n = read();
  48. k = read();
  49. for (int i = 0;i < n;i++) a[i].a = read();
  50. for (int i = 0;i < n;i++) a[i].b = read(), a[i].v = a[i].a / a[i].b + 1;///因为一天结束才扣电,而到了这天就算,所以取下整能过几天,加一是往后一天也算到了。
  51. ll l = 0, r = 2e12;
  52. while (l <= r) {
  53. ll mid = l + r >> 1;
  54. if (check(mid)) r = mid - 1;
  55. else l = mid + 1;
  56. }
  57. cout << (l > 2e12 ? -1 : l) << '\n';
  58. return 0;
  59. }

方法二

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. int n, k;
  5. ll a[200007], b[200007];
  6. bool check(ll mid) {
  7. int r = k;
  8. vector<int> sum(k);
  9. for (int i = 0;i < n;i++) {
  10. ll tmp = a[i];
  11. while (tmp / b[i] + 1 < k && r >= 0) {
  12. sum[tmp / b[i] + 1]++;
  13. tmp += mid;
  14. r--;
  15. }
  16. if (r < 0) return false;
  17. }
  18. for (int i = 1;i < k;i++) {
  19. sum[i] += sum[i - 1];
  20. if (sum[i] > i) return false;///充电次数超过天数,不可能实现
  21. }
  22. return true;
  23. }
  24. int main() {
  25. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  26. cin >> n >> k;
  27. for (int i = 0;i < n;i++) cin >> a[i];
  28. for (int i = 0;i < n;i++) cin >> b[i];
  29. ll l = 0, r = 2e12;
  30. while (l <= r) {
  31. ll mid = l + r >> 1;
  32. if (check(mid)) r = mid - 1;
  33. else l = mid + 1;
  34. }
  35. cout << (l > 2e12 ? -1 : l) << '\n';
  36. return 0;
  37. }

CF1132D Stressful Training的更多相关文章

  1. CF 3-6 2级组 D题 STRESSFUL TRAINING 紧张的比赛

    题目大概是这样的: 给出一个数列a[n] ,对于每一个数 a [i] 来说 都会在 T - - 时 -= b[i] 每个数都在任何时刻不能小于0 你可以在每次T - - 之前时给 一 个 a[i] + ...

  2. 【Codeforces 1132D】Stressful Training

    Codeforces 1132 D 题意:给\(n\)个电脑的电量和耗电速度,你可以买一个充电器,它的充电速度是每秒\(v\)单位,\(v\)你自己定.问最小的\(v\)能使得在\(k\)秒内每秒给某 ...

  3. Codeforces 1132D - Stressful Training - [二分+贪心+优先队列]

    题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有 $n$ 个学生,他们的电脑有初始电量 $a[1 \sim n]$,他们的电脑每分钟会耗 ...

  4. CF集萃1

    因为cf上一堆水题,每个单独开一篇博客感觉不太好,就直接放一起好了. CF1096D Easy Problem 给定字符串,每个位置删除要代价.求最小代价使之不含子序列"hard" ...

  5. Codeforces 1132 - A/B/C/D/E/F - (Undone)

    链接:http://codeforces.com/contest/1132 A - Regular Bracket Sequence - [水] 题解:首先 "()" 这个的数量多 ...

  6. CF1132.Educational Codeforces Round 61(简单题解)

    A .Regular Bracket Sequence 题意:给定“((” , “()” ,  “)(”,  “))”四种,问是否可以组成合法括号匹配 思路:设四种是ABCD,B可以不用管,而C在A或 ...

  7. Educational Codeforces Round 61 (Rated for Div. 2) D,F题解

    D. Stressful Training 题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有n台电脑,每台电脑都有初始电量ai,也有一个 ...

  8. CF 1132A,1132B,1132C,1132D,1132E,1132F(Round 61 A,B,C,D,E,F)题解

    A.Regular bracket sequence A string is called bracket sequence if it does not contain any characters ...

  9. hdu 4946 2014 Multi-University Training Contest 8

    Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. Linux和kali Linux 介绍

    常用的渗透测试平台 CTFTools kali (近亲 Ubuntu) Parrot Security OS PentestBox --由印度人开发,运行在Windows下的渗透测试环境 kali L ...

  2. vue 设置动态标题

    在 router/index.js 文件中设置 meta:{title:'标题'} 和 router.beforeEach,即可实现功能, 代码如下: import { createRouter, c ...

  3. Java 18 新特性:使用Java代码启动jwebserver

    前几天分享了Java 18 新特性:简单Web服务器的jwebserver命令行功能. 今天换一种方式,使用Java代码来实现一个静态资源服务器. 详细步骤我录了个视频放到B站了,感兴趣的小伙伴可以点 ...

  4. 基于mybatis的java代码生成存储过程

    问题: 项目中目前使用mybatis操作数据库,使用插件(mybatis-generator)自动生成代码,对于增改查,使用存储过程实现了一版本,方便使用. insert代码生成器用法: insert ...

  5. 什么是边缘CDN和虚拟CDN (vCDN)?

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 如今CDN有哪些局限性? 现如今,内容和游戏提供商正面临着越来越大的压力,它们需要向最终用户提 ...

  6. scrapy架构与目录介绍、scrapy解析数据、配置相关、全站爬取cnblogs数据、存储数据、爬虫中间件、加代理、加header、集成selenium

    今日内容概要 scrapy架构和目录介绍 scrapy解析数据 setting中相关配置 全站爬取cnblgos文章 存储数据 爬虫中间件和下载中间件 加代理,加header,集成selenium 内 ...

  7. 精华!一张图进阶 RocketMQ

    前 言 大家好,我是三此君,一个在自我救赎之路上的非典型程序员. "一张图"系列旨在通过"一张图"系统性的解析一个板块的知识点: 三此君向来不喜欢零零散散的知识 ...

  8. 探索ABP基础架构-下

    配置应用程序 ASP.NET Core 的配置系统提供了一个基于键值对的配置方法.它是一个可扩展的系统,可以从各种资源中读取键值对,例如 JSON 设置文件.环境变量.命令行参数等等. 设置配置值 默 ...

  9. strlen获取字符数组为什么是255

    为什么是255呢? strlen函数的规则是,读取到0则判断字符串结束. char为1字节,只有8位. 所以...... -1就是 1111 1111, -2就是 1111 1110, 直到-128: ...

  10. 696. Count Binary Substrings - LeetCode

    Question 696. Count Binary Substrings Example1 Input: "00110011" Output: 6 Explanation: Th ...