题目链接:点击查看

题目大意:火车上有n个乘客,编号分别为1~n,编号为i的人会在第ti分钟去打水,水箱每次只能给一个乘客使用,每位乘客都会使用水箱p分钟,当一位乘客想要去打水时,他会先看编号在他前面的乘客是否都在座位上,如果有人没在座位上,那么他会坐下来继续等待,否则就会去水箱处排队打水,当某一时刻有几位乘客想同时打水时,编号小的乘客会优先打水,其他人会在水箱前面继续等待,计算每个乘客打完水的时间

题目分析:面向题解编程。。。

因为题目好几处涉及到了最值,比如最小编号,最小时间,所以我们需要选择合适的容器进行处理,以达到减小时间复杂度并方便操作的目的

这里我们选择的容器有:优先队列、队列、集合

首先建立两个优先队列,sitting与waiting,分别储存“坐在座位上且时间没到的人”与“坐在座位上且时间早就到达的人”

再建立一个队列,queuing,储存“在水箱前面排队的人”

最后建立一个集合,empty_seat,储存空的位置,我们可以很方便的用*empty_seat.begin()获取编号最小的空位置

这样一来按照题目直接模拟就好了,需要注意的细节如下:

  1. 因为整个操作是对于当前时间而言的,所以每次只要时间更新,sitting与waiting都要实时更新
  2. 操作优先级:queuing > waiting > sitting
  3. 对于每次sitting与waiting的更新,我们分成两个部分:
    1. 若此时的时间now之前有人在水箱前面打水

      1. sitting直接加入到水箱后排队
      2. waiting里的人继续等待(因为waiting里的人早就满足时间条件了,不满足的是编号条件,这里一定需要想清楚再写)
    2. 若此时的时间now之前没有人在水箱前面打水
      1. sitting先加入到waiting中(满足条件者)
      2. waiting再加入到queuing中(满足条件者)

然后就是实现了,剩下的看注释吧

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;struct Node
{int pos,start_time;
};struct cmp_waiting
{bool operator()(const Node& a,const Node& b){return a.pos>b.pos;}
};struct cmp_sitting
{bool operator()(const Node& a,const Node& b){if(a.start_time!=b.start_time)return a.start_time>b.start_time;return a.pos>b.pos;}
};
//优先级:queuing > waiting > sitting
priority_queue<Node,vector<Node>,cmp_waiting>waiting;
priority_queue<Node,vector<Node>,cmp_sitting>sitting;
queue<Node>queuing;
set<int>empry_seat;LL ans[N];int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int n;LL p,now;scanf("%d%lld",&n,&p);for(int i=1;i<=n;i++){Node temp;scanf("%d",&temp.start_time);temp.pos=i;sitting.push(temp);}now=sitting.top().start_time;empry_seat.insert(n+1);//将n+1置空,方便操作 while(sitting.size()||queuing.size()||waiting.size()){ while(queuing.size()&&queuing.front().start_time<=now)//如果有人在排队,则优先处理排队的人 {now+=p;//当前时间更新后,记得实时更新sitting和waiting ans[queuing.front().pos]=now;while(sitting.size()&&sitting.top().start_time<=now)//如果有新的人满足时间条件了
//注意这里为什么值从sitting里拿而不在waiting里拿,是因为waiting里的人早就满足时间约束了,只是不满足编号约束,所以在这里肯定仍然不满足编号约束{if(sitting.top().pos<*empry_seat.begin())//前面没人在接水,直接去排队 {queuing.push(sitting.top());empry_seat.insert(sitting.top().pos);//当前位置空了 sitting.pop();}else//否则加入到waiting里去等{waiting.push(sitting.top());sitting.pop();}}empry_seat.erase(queuing.front().pos);//接完水就回到座位上了 queuing.pop();}if(queuing.empty()&&waiting.empty())//如果排队的人和等待的人都为空,说明时间太早了,直接快进 now=max(now,(LL)sitting.top().start_time);while(sitting.size()&&now>=sitting.top().start_time)//对满足时间要求的人操作 {waiting.push(sitting.top());sitting.pop();}while(waiting.size()&&waiting.top().pos<*empry_seat.begin()){queuing.push(waiting.top());empry_seat.insert(waiting.top().pos);//只要离开座位就要加入这里 waiting.pop();}}for(int i=1;i<=n;i++)printf("%lld ",ans[i]);return 0;
}

CodeForces - 1248E Queue in the Train(大模拟)相关推荐

  1. 1014 Waiting in Line (30 分) 【未完成】【难度: 难 / 知识点: 大模拟】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805498207911936 大模拟代码有时间补

  2. ZOJ 3879(大模拟)

    传送门 题面:Capture the Flag Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge In comp ...

  3. ccf 202012-3 带配额的文件系统(大模拟)

    题外: 啊这,大半年没来csdn了,都长草了.回来练练机试内容吧,现在敲个模拟题,磕磕绊绊的..但是这大模拟恶心也是真恶心... 思路: 开始的时候跑偏了,本来是用的邻接表直接建边,但是问题是不在同一 ...

  4. “景驰科技杯”2018年华南理工大学程序设计竞赛 C Youhane's Undergraduate Thesis (大模拟)

    链接:https://www.nowcoder.com/acm/contest/94/C 大家都知道想从华南理工大学的本科毕业并不是一件简单的事情,作为一名大四即将毕业的学生,优酱正在为她的毕业论文愁 ...

  5. 20201104大模拟(一)

    20201104大模拟(一) 开错题了我吐了,赛后A一发过,绝了 B是什么deng西,我得有一段时间不想看到植物大战僵尸了,有一些边界问题 C是在计算的过程中的大模拟 D是思维, 总体来说其实还好,不 ...

  6. [BZOJ2548][Ctsc2002]灭鼠行动(大模拟)

    题目描述 传送门 题解 又是一道大模拟... 需要注意的几个地方: 1.一个时刻x+时间单位x~y操作的顺序是:时刻x老鼠繁殖.时刻x放武器.判断是否发生鼠疫.时间单位x~y老鼠移动. 2.只有某一个 ...

  7. 【第一届INT杯】 INT lpy的火柴游戏(大模拟)

    题目链接:https://www.coder.ac.cn/problem/INT1005 题解:这里就不多说了,也没有答案,没有数据.下午想了挺久的,总还是有一点收获的. 总结收获: 1.大模拟轻易别 ...

  8. [BZOJ1033][ZJOI2008]杀蚂蚁antbuster(大模拟)

    题目描述 传送门 题解 bz的题面真心不爽,建议去codevs 比较良心的一道大模拟,题面写的比较清楚,也没有什么坑 几个需要注意的地方 1.对于每一只蚂蚁来说,年龄=秒数-1 2.选择方向的过程是: ...

  9. AC日记——神奇的幻方 洛谷 P2615(大模拟)

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

最新文章

  1. matlab p-tite分割图像,P'tite fourmi
  2. python复制文件的代码_python 复制文件流程
  3. python28 excel读取模块xlrd
  4. 京东回应拖欠神州 3 亿多元货款;苹果考虑将第三方浏览器和邮件设为默认;PS 诞生 30 周年| 极客头条...
  5. Java进阶1. Synchronized 关键字
  6. 第二阶段个人总结10
  7. android 8.1没声音,RingtonePreference无法在Android 8.1上添加新的铃声
  8. 非平稳时间序列突变检测 -- Bernaola Galvan分割算法
  9. trend函数用oracle实现,使用TREND函数和LINEST函数做销售预测或成本分析
  10. 我只想说“独孤求败”与“东方不败”是不同的!
  11. Centos7上使用Kind搭建Kubernetes环境
  12. 【明日方舟 人工智能】在罗德岛学习人工智能的日子 (一)
  13. 下次约会时,让人工智能做你的僚机!
  14. 爬虫实战:链家租房数据爬取,实习僧网站数据爬取
  15. C# 面向对象学习笔记
  16. 2023年AP微观经济学考什么?
  17. 字符串匹配 python
  18. vue中实现动画效果--三种方式
  19. v18.02 鸿蒙内核源码分析(源码结构) | 内核文件各自含义 | 百篇博客分析HarmonyOS源码
  20. 转 《图说区块链》读书笔记(完整版)

热门文章

  1. python文件处理seek_python文件操作 seek(),tell()
  2. SpringSecurity集中式整合之授权操作
  3. Nginx负载均衡策略之ip_hash
  4. Spring boot中最大连接数、最大线程数与最大等待数在生产中的异常场景
  5. 分布式架构的session问题
  6. Lambda表达式的省略模式【应用】
  7. aop简介-aop开发明确的事
  8. Java实现消息发送
  9. spring配置详解-复杂类型注入
  10. Spring的@Configuration配置类-Full和Lite模式