链接:Atcoder。
链接:洛谷。
算法难度:B。
思维难度:B。
调码难度:A。
综合评价:普及+/提高。
堆/set。
我们需要实现以下功能(该容器可以手写堆实现,也可以用set):支持快速插入删除,并能够随时取出所有元素中的最小值。我们用其中一个存储吃完面条回来的人的编号、时间的组合(结构体Info),另一个存储现在队列中存在的人的编号。每次操作将所有时间小于t的“吃完面条回来的人”入队,并将该任务删除,之后将w的面条加到队列中编号最小的人身上,并添加回归任务“这个人在s+t的时间出完面条归队”,然后在队列中删除这个人。最后输出每个人的面条数目即可。
O(n+m*log(n)),因为set、堆等都有log级别的代价。
迭代器用法和指针基本相同。
- #include
- #define N 220000
- using namespace std;
- struct Info{
- long long node,ttime;
- bool operator<(Info ot)const{
- if(ttime==ot.ttime){
- return node
- }
- return ttime
- }
- };
- set
d={}; - //回归任务
- set<long long>zd={};
- //队列信息
- long long sum[N]={},m=0,n=0;
- //sum就是面条数目
- int main(){
- scanf("%lld%lld",&n,&m);
- for(long long i=1;i<=n;i++){
- zd.insert(i);
- }
- //输入,并记录每个人都在队列中
- for(long long i=1;i<=m;i++){
- long long s=0,t=0,w=0;
- scanf("%lld%lld%lld",&t,&w,&s);
- while(d.empty()==false&&d.begin()->ttime<=t){
- zd.insert(d.begin()->node);
- d.erase(d.begin());
- }
- //完成需要完成的回归任务
- if(zd.empty()==false){
- sum[*zd.begin()]+=w;
- d.insert({*zd.begin(),t+s});
- zd.erase(zd.begin());
- }
- //如果可以,就让队首的人得到面条离开一段时间
- }
- for(long long i=1;i<=n;i++){
- printf("%lld\n",sum[i]);
- }
- //输出答案
- return 0;
- }
·注意
手写堆很长,不推荐。
-
相关阅读:
Vector-常用CAN工具 - CANoe入门到精通_01
【LeetCode:637. 二叉树的层平均值 | bfs】
连续 3 年 40% 增长 续费率近 110%:纷享销客增长的底层逻辑
JavaScript-mooc(纯分享)
Java中String对象的replaceAll方法调用性能优化小技巧
ATtiny88初体验(一):点灯
Git 的基本概念和使用方式
计算点云每个点与Z轴的垂直度(附open3d python代码)
关于电影的HTML网页设计—— 电影小黄人6页 HTML+CSS+JavaScript
【小沐学Unity3d】3ds Max 骨骼动画制作(蒙皮修改器skin)
-
原文地址:https://blog.csdn.net/sluckystar/article/details/132956962