多队列模拟. 与POJ #1025 Department类似, 不过简化很多. 貌似这类模拟题经常出现. 用STL中的优先队列 (priority_queue<>) 很好写.


这题我写得很不顺, 老年选手退步太快, 记录一下我犯的一个很隐蔽的错误, 从前对此毫无认识, 想想都可怕, 太菜了.

这道题优先队列里维护的事件 (event) 是等待.

释放这些等待的先后顺序如下:

在同一队列 (此"队列"指某个office门前的队列, 与"优先队列"中的"队列"含义不同;下同) 中的两个事件, 按(开始等待时刻, 学号)这两个关键字排序. 在不同队列中的两事件按开始等待的时刻排序.

思路是比较容易想到的. 但我的实现里有个很subtle的错误.

Wrong implementation

#include <bits/stdc++.h>
using namespace std; const int N{1<<14}, M{1<<7};
int s[N], res[N];
vector<pair<int,int>> r[N]; // registration
int avail[M];
int n, m, k; struct W{
int id, beg, idx;
int des()const{
return r[id][idx].first;
}
int dur()const{
return r[id][idx].second;
}
int num()const{
return s[id];
}
int end()const{
return max(beg, avail[des()])+dur(); // error-prone
}
W next(){
return {id, end()+k, idx+1};
}
void out(){
cout<<id<<' '<<beg<<' '<<idx<<' '<<avail[des()]<<endl;
}
}; // greater<_Tp> is a function object
// constexpr std::greater<_Tp>::operator()(const _Tp &, const_Tp &)const bool cmp(const W &a, const W &b){ //! > must be a const
if(a.des()!=b.des()){
return a.beg>b.beg;
}
else{
return a.beg!=b.beg?a.beg>b.beg:a.num()>b.num();
}
} priority_queue<W, vector<W>, decltype(cmp)*> que(cmp); int main(){
cin>>n>>m>>k;
for(int i=0; i<n; i++){
int q, t;
cin>>s[i]>>t>>q;
for(; q--; ){
int o, t;
cin>>o>>t;
r[i].push_back({o, t});
}
que.push({i, t+k, 0});
} for(; !que.empty(); ){
W top=que.top();
que.pop();
if(top.idx<r[top.id].size()-1){
que.push(top.next());
}
else{
res[top.id]=top.end();
}
avail[top.des()]=top.end();
}
for(int i=0; i<n; i++)
cout<<res[i]<<endl;
return 0;
}

注意其中的比较函数cmp:

bool cmp(const W &a, const W &b){  //! > must be a const
if(a.des()!=b.des()){
return a.beg>b.beg;
}
else{
return a.beg!=b.beg?a.beg>b.beg:a.num()>b.num();
}
}

首先必须认识到: 优先队列要求元素的键值 (key) 在所定义的比较函数下是全序的 (totally ordered).

If $X$ is totally ordered under $\le$, then the following statements hold for all $a, b$ and $c$ in $X$:

if $a \le b$ and $b \le a$ then $ a=b$ (antisymmetry);

if $a \le b$ and $b\le c$ then $a \le c$ (transitivity);

$a \le b$ or $b \le a$ (totality).

我所定义的比较函数并不是全序的. 问题中的集合$X$内的元素是一个三元组$(id, des, time)$. 我们定义的比较函数cmp是一个strict weak ordering (<). 这个binary relation应当满足

if $a < b$ and $b<c$, then $a<c$

$a< b$ or $ b<a$ or $a=b$.

但是据此会导出矛盾, 考虑

$a =(id_1, des_1, t), b=(id_2, des_1, t), c=(id_3, des_2, t), id_1 < id_2 \Longrightarrow a > b, a=c, b=c$.

矛盾!

因而这个比较函数不是全序的.

但是可以略微改一下:

以$time$为第一关键字, $des$为第二关键字, $id$为第三关键字.

这样不但思路更清楚, 代码也可以简化

Implementation

#include <bits/stdc++.h>
using namespace std; const int N{1<<14}, M{1<<7};
int s[N], res[N];
vector<pair<int,int>> r[N]; // registration
int avail[M];
int n, m, k; struct W{
int id, beg, idx;
int des()const{
return r[id][idx].first;
}
int dur()const{
return r[id][idx].second;
}
auto make_tuple()const{
return std::make_tuple(beg, des(), num());
}
int num()const{
return s[id];
}
bool operator<(const W &rhs)const{
return make_tuple() > rhs.make_tuple();
}
int end()const{
return max(beg, avail[des()])+dur(); // error-prone
}
W next(){
return {id, end()+k, idx+1};
}
void out(){
cout<<id<<' '<<beg<<' '<<idx<<' '<<avail[des()]<<endl;
}
}; priority_queue<W> que; int main(){
cin>>n>>m>>k;
for(int i=0; i<n; i++){
int q, t;
cin>>s[i]>>t>>q;
for(; q--; ){
int o, t;
cin>>o>>t;
r[i].push_back({o, t});
}
que.push({i, t+k, 0});
} for(; !que.empty(); ){
W top=que.top();
que.pop();
if(top.idx<r[top.id].size()-1){
que.push(top.next());
}
else{
res[top.id]=top.end();
}
avail[top.des()]=top.end();
}
for(int i=0; i<n; i++)
cout<<res[i]<<endl;
return 0;
}

hihoCoder 1401 Registration的更多相关文章

  1. struts2启动报错:ERROR com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor - Conversion registration error

    [framework] 2019-12-05 11:34:05,441 - org.springframework.web.context.ContextLoader -5352 [RMI TCP C ...

  2. hihocoder -1121-二分图的判定

    hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...

  3. Hihocoder 太阁最新面经算法竞赛18

    Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...

  4. hihoCoder太阁最新面经算法竞赛15

    hihoCoder太阁最新面经算法竞赛15 Link: http://hihocoder.com/contest/hihointerview24 题目1 : Boarding Passes 时间限制: ...

  5. 【hihoCoder 1454】【hiho挑战赛25】【坑】Rikka with Tree II

    http://hihocoder.com/problemset/problem/1454 调了好长时间,谜之WA... 等我以后学好dp再来看为什么吧,先弃坑(╯‵□′)╯︵┻━┻ #include& ...

  6. 【hihocoder#1413】Rikka with String 后缀自动机 + 差分

    搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...

  7. 【hihoCoder】1148:2月29日

    问题:http://hihocoder.com/problemset/problem/1148 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 思路: 1. 将问题转换成求两个日 ...

  8. 【hihoCoder】1288 : Font Size

    题目:http://hihocoder.com/problemset/problem/1288 手机屏幕大小为 W(宽) * H(长),一篇文章有N段,每段有ai个字,要求使得该文章占用的页数不超过P ...

  9. 【hihoCoder】1082: 然而沼跃鱼早就看穿了一切

      题目:http://hihocoder.com/problemset/problem/1082 输入一个字符串,将其中特定的单词替换成另一个单词   代码注意点: 1. getline(istre ...

随机推荐

  1. QTableView 添加按钮

    这里说一下怎么在QTableView添加一个按钮 添加两个按钮的例子在这篇文章里:QTableView 一列添加两个按钮 效果是点击button弹出一个对话框. 看一下ButtonDelegate的代 ...

  2. 让 innerHTML 进来的 script 代码跑起来

    今天来简单聊聊如何让 innerHTML 进来的 scrip 代码跑起来的问题. 前台请求一个接口,接口返回一些 HTML 标签拼接成的字符串,以供前端直接 innerHTML 生成 DOM 元素,这 ...

  3. 移动端调试利器 JSConsole 介绍

    先看这篇文章 Web应用调试:现在是Weinre和JSConsole,最终会是WebKit的远程调试协议. 我们先不看未来,从此文可见,当下的移动端调试还是 Weinre 和 JSConsole 的天 ...

  4. 【位运算经典应用】 N皇后问题

    说到位运算的经典应用,不得不说N皇后问题. 学过程序设计的都知道N皇后问题,没听过也没关系.很简单,最传统的的N皇后问题是这个样子的,给你一个n * n大小的board,让你放n个皇后(国际象棋),要 ...

  5. .Net Core 自定义序列化格式

    序列化对大家来说应该都不陌生,特别是现在大量使用WEBAPI,JSON满天飞,序列化操作应该经常出现在我们的代码上. 而我们最常用的序列化工具应该就是Newtonsoft.Json,当然你用其它工具类 ...

  6. 【分布式协调】之理解paxos

    感叹一下 不得不说近几年国内软件行业发生了巨大的变化,之前几乎所有应用都围绕桌面展开,而近几年很多让人神魂颠倒的关键词一个接一个的映入眼帘:web2.0.移动应用.云计算.大数据.互联网的浪潮一波接着 ...

  7. 大新闻!HoloLens即将入华商用

    昨天微软搞了大新闻,Terry和Alexi到了深圳,在WinHEC大会上宣布了2017上半年HoloLens正式入华商用. 关于HoloLens的技术原理和细节官方文档和报道已经披露很多了,他是一款真 ...

  8. mac搭建mamp环境

    1 先安装homebrew; 执行:cd /usr/local; 非root用户执行: ruby -e "$(curl -fsSL https://raw.githubusercontent ...

  9. WEB 文件上传

    关键:<input name="file" type="file"/> 然后,在外面<form>层中必须写上:enctype=" ...

  10. PotPlayer 1.6.52965 美化版|视频播放器

    Potplayer播放器,基本上可以解析大部分的视频格式.作为单机版的视频播放器很不错的选择! Potplayer,只为播放而生! exp: 点击下载