题解:小S与机房里的电脑 Computer_C++算法竞赛_贪心_二分答案_模拟_数据结构
文章目录
- 小S与机房里的电脑 Computer
- 传统题
- 题目描述
- 输入格式
- 输出格式
- 样例
- 样例输入 1
- 样例输出 1
- 样例输入 2
- 样例输出 2
- 提示
- 解题思路
- AC Code
- End
小S与机房里的电脑 Computer
传统题
- 时间限制: 1000ms
- 内存限制: 256MiB
题目描述
最近小S想带他的学生打组队娱乐赛,比赛规定每队三个人只能其中一个人用电脑进行代码的编写。
但是现在隔壁教室因为上大型集训课拿走了所有的充电器,导致最后只剩下一个充电器可以拿来充电。但是 n n n 个队伍需要 n n n 台电脑,并且组队娱乐赛要进行 m m m 分钟,每台电脑有初始的电量 a i a_i ai ,每分钟的耗电量 b i b_i bi 。没有办法,小S只能通过他的电路知识来改装这个充电器,使得它具有足够的功率来帮助同学们完成这场比赛。
但是功率越大危险度越高,小S希望你帮他计算一下,充电器至少每分钟要充多少电才能满足大家的需求。
输入格式
- 第一行一个正整数 T T T 代表多组数据的组数
- 第二行两个整数 n n n 和 m m m
- 第三行 n n n 个整数 a i a_i ai
- 第四行 n n n 个整数 b i b_i bi
输出格式
输出一行整数,代表满足比赛需求的充电器每分钟最小的充电量,若无法满足需求,则输出 -1。
样例
样例输入 1
2
2 4
3 2
4 2
2 2
2 10
3 15
样例输出 1
5
-1
样例输入 2
2
1 5
4
2
1 6
4
2
样例输出 2
1
2
提示
全部数据包括:
- n ≤ 2 × 1 0 5 n \leq 2 \times 10^5 n≤2×105
- 1 ≤ m ≤ 2 × 1 0 5 1 \leq m \leq 2 \times 10^5 1≤m≤2×105
- 1 ≤ a i ≤ 1 0 12 1 \leq a_i \leq 10^{12} 1≤ai≤1012
- 1 ≤ b i ≤ 1 0 7 1 \leq b_i \leq 10^7 1≤bi≤107
其中,30%的数据保证 n ≤ 100 n \leq 100 n≤100
解题思路
提示:这里光看有些抽象,结合下面的 Code 理解起来更容易。
思路:考虑二分答案,二分最小的充电功率。
其中可以用 vector 建桶, v e s [ i ] ves[i] ves[i] 表示存活时间到 i i i 的电脑的结构体下标数组,
去枚举 vector 的第一维下标,同时设置一个变量 n o w T nowT nowT 表示当前时间,
根据贪心的思想,选择当前快要没电的那个:存活时间到 i i i 的先充电
如果当前时间大于第一维下标,说明电脑修不过来了,返回 false;
否则, n o w T = m nowT =m nowT=m 时,说明执行完任务了,退出。
小总结:
check 中的循环调换了常理。原本正常的思路应该是枚举 n o w T nowT nowT,用堆维护当前的最小存活时间(如 AC 代码下面的代码),
但是这样复杂度 O ( log ( 1 0 12 ) × m × log ( n ) ) O(\log(10^{12}) \times m \times \log(n)) O(log(1012)×m×log(n)),但“好心”的出题人卡 log,说明不能这样。
于是,我们转而枚举第一维下标解决了问题,这种思路很值得积累。
程序运行过程:
- 输入,用结构体存储每一台电脑的基础信息和存活时间。
- 二分答案,充电功率,往小了二分。
check(){
- 预处理每一台电脑,用 vector 建桶,这样查询插入复杂度 O ( 1 ) O(1) O(1)。
- 不断枚举 vector 的第一维下标,不断修电脑,直到有的电脑最大存活时间小于当前枚举的时间,退出。
- 一直执行至 n o w T = m nowT = m nowT=m,说明可以完成任务,返回 TRUE。
}
AC Code
这道题貌似要加快读,不然会被卡常。快读讲解文章
#include <bits/stdc++.h>
using namespace std;typedef long long ll;int T, n, m;struct Node{ll a, b;ll t_a; // 表示当前还能存活多长时间
}N[100005];
vector <int> A[100005];bool check(ll x){for(int i = 0; i <= m; i ++) A[i].clear(); // 先清空,后使用for(int i = 1; i <= n; i ++){ // 初始化赋值N[i].t_a = N[i].a;if(N[i].b != 0 && N[i].t_a / N[i].b + 1 <= m){ // 如果存活时间在m之内,说明还有计算的必要(它可能会撑不住)A[N[i].t_a / N[i].b + 1].push_back(i); // 塞到对应的桶中}}int nowT = 1; // 当前时间的计数器for(int i = 1; i <= m; i ++){ // 枚举m个时间单位,作为判断标准(可以理解为理想化的时间)while(A[i].size() > 0){ // 这个内层循环最多执行n次,所以总时间复杂度不是O(n^2),是线性O(n)的if(nowT > i){ // 如果当前时间>i,说明已经超时了return false;}if(nowT == m){return true; // 说明顺利执行完m秒,可以返回}int pos = A[i].back(); A[i].pop_back();N[pos].t_a += x; // 把充电器给他充上。因为当前的压线时间是i,所以肯定要先给快没电的(也就是当前时间i)充电。至于先后顺序就无所谓了。nowT ++;if(N[pos].t_a / N[pos].b + 1 <= 1LL * m){ // 注意a[i]<=1e12,m不强转ll可能会出问题A[N[pos].t_a / N[pos].b + 1].push_back(pos);}
// cout << "debug: " << i << " " << A[i].size() << " " << nowT << endl;}
// cout << "debug_i:" << i << endl;}return true;
}template <typename T>
void read(T &w){ // 防止卡常,加快读w = 0;char c = getchar();for(; c < '0' || c > '9'; c = getchar());for(; c >= '0' && c <= '9'; c = getchar()){w = (w << 1) + (w << 3) + (c ^ 48);}
}int main()
{for(read(T); T --; ){read(n), read(m);for(int i = 1; i <= n; i ++){read(N[i].a);}for(int i = 1; i <= n; i ++){read(N[i].b);}
// cout << check(10) << endl;ll l = 0, r = 1e12, ans = -1;while(l <= r){ll mid = (l + r) >> 1;if(check(mid)){ans = mid;r = mid - 1;}else{l = mid + 1;}}printf("%lld\n", ans);}return 0;
}
附:上面提到的被卡超时的代码
//超时TLE
#include <bits/stdc++.h>
using namespace std;typedef long long ll;const int MAXN = 2e5 + 7;int T , n , m;struct Node{ll a , b;ll t_a;
}no[MAXN];bool check(ll x){map < int , vector <int> > vis;for(int i = 1; i <= n; i ++){ //预处理no[i].t_a = no[i].a;if(no[i].b != 0 && no[i].t_a / no[i].b < 1LL * m){vis[no[i].t_a / no[i].b].push_back(i);}else{//pass}}for(int tim = 0; tim < m; tim ++){if(vis.empty()){return true;}int pos = vis.begin()->first;if(pos < tim){return false;}ll t1 = vis[pos].back(); vis[pos].pop_back();if(vis[pos].size() == 0){vis.erase(vis.begin());}no[t1].t_a += x;if(no[t1].t_a / no[t1].b < m){vis[no[t1].t_a / no[t1].b].push_back(t1);}}return true;
}int main()
{for(scanf("%d" , &T); T; --T){scanf("%d %d" , &n , &m);for(int i = 1; i <= n; i ++){scanf("%lld" , &no[i].a);}for(int i = 1; i <= n; i ++){scanf("%lld" , &no[i].b);}
// cout << check(5) << endl;ll l = 0 , r = 1e12 , ans = -1;while(l <= r){ //二分充电功率,往小了二分ll mid = (l + r) >> 1;if(check(mid)){ans = mid;r = mid - 1;}else{l = mid + 1;}}printf("%lld\n" , ans);}return 0;
}
End
感谢大家观看,祝大家 AC!
这里是 YLCHUP,拜拜ヾ(•ω•`)o
广告:本文在洛谷博客同步发送,个人洛谷账号:ylch
相关文章:
题解:小S与机房里的电脑 Computer_C++算法竞赛_贪心_二分答案_模拟_数据结构
文章目录 小S与机房里的电脑 Computer传统题题目描述输入格式输出格式样例样例输入 1样例输出 1样例输入 2样例输出 2 提示解题思路AC CodeEnd 小S与机房里的电脑 Computer 传统题 时间限制: 1000ms内存限制: 256MiB 题目描述 最近小S想带他的学生打组队娱乐赛,…...
Python @staticmethod、super().__init__()和self
最近在看代码,由于之前没有系统学习过Python,就有些知识点不是很清楚,这里整理一下,方便以后查阅。 Python中的staticmethod\super.init和self Python 装饰器staticmethod和classmethod的作用与区别作用区别代码演示 super() 函数…...

Linux网络:应用层协议HTTP(一)
一、什么是HTTP协议 虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一。 在互联网世界中,HTTP(HyperText Transfer Protocol&…...
Tomcat底层原理
Tomcat是一个开源的Java Servlet容器,它实现了Java Servlet和JavaServer Pages (JSP) 技术,用于运行Java Web应用。它是由Apache软件基金会开发和维护的。以下是对Tomcat底层原理的详细解析: 1. 启动流程 Tomcat的启动流程主要分为以下几个…...

【Linux】Linux环境设置环境变量操作步骤
Linux环境设置环境变量操作步骤 在一些开发过程中本地调试经常需要依赖环境变量的参数,但是怎么设置对小白来说有点困难,今天就介绍下具体的操作步骤,跟着实战去学习,更好的检验自己的技术水平,做技术还是那句话&…...

C语言:键盘录入案例
主要使用了scanf; scanf的使用方法和注意事项: 1.作用: 用于接收键盘输入的数据并赋值给对应的变量 2.使用方式; scanf("占位符",&变量名); 3.注意事项; 占位符后面的的变量要对应 第一个参数中不写换行 案例1…...
Nginx 中如何实现请求的排队机制?
Nginx 中如何实现请求的排队机制? 在当今数字化的时代,网站和应用的流量就如同潮水一般,时涨时落,时急时缓。想象一下,当流量如洪水猛兽般汹涌而来,服务器就像是那抗洪的堤坝,如果没有有效的管…...

synergy配置
今天介绍一个电脑同步软件synergy。 我们开发时一般会用两套设备,如果使用两套键盘操作起来会很麻烦,这个软件就是解决这个问题,可以使用一套键盘同时操作两台电脑,另一台作为客户端被控制。 安装 在两台电脑上各自下载安装syne…...

Qt开发网络嗅探器03
数据包分析 想要知道如何解析IP数据包,就要知道不同的IP数据包的包头结构,于是我们上⽹查查资料: 以太网数据包 ARP数据包 IPv4 IPv6 TCP UDP ICMP ICMPv6 根据以上数据包头结构,我们就有了我们的protocol.h文件,声明…...

抖音短视频seo矩阵系统源码开发技术分享(二)--SaaS开源
目录 市场背景分析 一、抖音短视频seo矩阵系统开发部署流程 二、 源码开发功能构思 三、 抖音短视频seo源码开发部署注意事项 四、 部分开发代码展示 市场背景分析 抖音短视频seo矩阵系统是通过不同平台不同账号之间建立联系,通过将同一品牌下不同平台不同账号…...
git-常用基础指令
一、基本指令 1. 配置用户名和邮箱 git config --global user.name "Your Name" git config --global user.email "your.emailexample.com"2. 初始化仓库 git init3. 克隆仓库 git clone <repository_url>4. 查看当前状态 git status5. 添加文件…...

Inconsistent Query Results Based on Output Fields Selection in Milvus Dashboard
题意:在Milvus仪表盘中基于输出字段选择的不一致查询结果 问题背景: Im experiencing an issue with the Milvus dashboard where the search results change based on the selected output fields. Im working on a RAG project using text data conv…...

视觉巡线小车——STM32+OpenMV
系列文章目录 第一章:视觉巡线小车——STM32OpenMV(一) 第二章:视觉巡线小车——STM32OpenMV(二) 第三章:视觉巡线小车——STM32OpenMV(三) 第四章:视觉巡…...
升级TrinityCore 服务器硬件
升级服务器 原服务器架构:Ubuntu装VirtualBox装Ubuntu虚拟机 原配置: 宿主机 内存4G 内核4 usb外接硬盘 Ubuntu虚拟机 内存1756MB 内核4 ip 192.168.0.12 升级服务器架构:FreeBSD装bhyve装Ubuntu虚拟机 新配置:宿主机 内存…...

NVidia 的 gpu 开源 Linux Kernel Module Driver 编译 安装 使用
见面礼,动态查看gpu使用情况,每隔2秒钟自动执行一次 nvidia-smi $ watch -n 2 nvidia-smi 1,找一台nv kmd列表中支持的 GPU 的电脑,安装ubuntu22.04 列表见 github of the kmd source code。 因为 cuda sdk 12.3支持最高到 ubu…...

win7显卡驱动更新后msvcp140.dll丢失的解决方法
msvcp140.dll是一个 DLL(动态链接库)文件,它是 Microsoft Visual C 2015 Redistributable Package 的一部分。这个文件包含 C 应用程序在运行时所需的标准库函数,主要涉及执行与 C 编程语言相关的操作,如内存管理、数学…...

(11)Python引领金融前沿:投资组合优化实战案例
1. 前言 本篇文章为 Python 对金融的投资组合优化的示例。投资组合优化是从一组可用的投资组合中选择最佳投资组合的过程,目的是最大限度地提高回报和降低风险。 投资组合优化是从一组可用的投资组合中选择最佳投资组合的过程,目的是最大限度地提高回报…...
git删除本地远程分支
gitlab删除远程分支 要删除GitLab上的远程分支,你可以使用Git命令行工具。以下是删除远程分支的步骤和示例代码: 首先,确保你已经在本地删除了分支。删除本地分支的命令是: git branch -d <branch_name> 如果分支没有被合…...

前端-04-VScode敲击键盘有键入音效,怎么关闭
目录 问题解决办法 问题 今天正在VScode敲项目,不知道是按了什么快捷键还是什么的,敲击键盘有声音,超级烦人啊!!于是我上网查了一下,应该是开启了VScode的键入音效,下面是关闭键入音效的办法。…...
JMeter数据库连接操作及断言
一、数据库操作 应用场景: 接口自动化数据校验:用于验证接口返回的数据与数据库中的数据是否一致。特殊业务:处理一些与数据库相关的特殊业务逻辑。性能测试:测试数据库的性能,如查询、更新等操作的响应时间。 连接数…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...