您现在的位置是:亿华云 > 应用开发
乒乒乓乓:这点小事儿,算什么?
亿华云2025-10-03 20:25:43【应用开发】9人已围观
简介本文转载自微信公众号「Piper蛋窝」,作者Piper蛋。转载本文请联系Piper蛋窝公众号。一道 PAT 原题,被称为「PAT史上最麻烦题目」:PAT 原题英文链接:https://pintia.c
本文转载自微信公众号「Piper蛋窝」,算什么作者Piper蛋。乒乒乓乓转载本文请联系Piper蛋窝公众号。事儿
一道 PAT 原题,算什么被称为「PAT史上最麻烦题目」:
PAT 原题英文链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805472333250560 AcWing 翻译:https://www.acwing.com/problem/content/1505/原题
一个乒乓球俱乐部共有K张乒乓球台,乒乒乓乓编号为1~K 。事儿
对于任意一对球员,算什么当他们到达时如果有多个球台可用,乒乒乓乓那么他们就会被安排到编号较小的事儿那个球台上打球。
如果所有球台都被占用了,算什么他们就只能排队等待了。乒乒乓乓
假设每对球员最多只允许打两小时球。事儿
你需要计算每个排队等候的算什么人的等待时间以及每个球台当天有多少对球员在上面打球。
另外,乒乒乓乓让这个事情变得复杂的事儿是,俱乐部为 VIP 球员保留了一些球台。
当一个 VIP 球台空出时,等待队伍中的第一对 VIP 球员将优先使用这个球台。
如果此时等待队伍中没有 VIP,则排在等待队伍的第一对球员可以使用这个球台。
另一方面,当轮到一对 VIP 球员打球时,如果没有 VIP 球台可用,那么他们将被视作普通球员处理。
补充:
1、当等待队伍中有 VIP 球员并且有空闲 VIP 球台时,必须优先分配 VIP 球员,高防服务器并且必须分配他们 VIP 球台(优先分配编号较小的),直至 VIP 用户或 VIP 球台分配完为止。
2、期望打球时间超过两小时的,只能允许打两小时。
3、当多对球员的开始打球时间相同时,先输出到达时间早的球员的信息。
4、当等待球员中没有 VIP 时,VIP 球台视作普通球台处理,当可用球台中没有 VIP 球台时,VIP 球员视作普通球员处理。
输入格式
第一行包含整数N,表示共有N对球员。
接下来N行,每行包含两个时间以及一个 VIP 标识,HH:MM:SS----到达时间,p----打球时间(单位:分钟),tag----如果是 ,说明这是一对 VIP,如果是 ,说明不是 VIP。
保证到达时间在 08:00:00 至 21:00:00 之间,网站模板这是俱乐部的营业时间。
保证每对球员的到达时间都不相同。
再一行包含两个整数K和M,表示球台数量以及 VIP 球台数量。
最后一行包含M个整数,表示 VIP 球台的编号。
输出格式
首先输出每对球员的到达时间,开始打球时间,等待时间。
每对球员的信息占一行,按开始打球时间从早到晚的顺序依次输出。
等待时间必须四舍五入为整数分钟。
如果一对球员在 21:00:00 之前(不包括 21:00:00)不能得到一张球台,那么无需输出他们的信息。
再输出一行,K个整数,表示每个球台服务的球员对数。
数据范围
输入样例:
9
20:52:00 10 0
08:00:00 20 0
08:02:00 30 0
20:51:00 10 0
08:10:00 5 0
08:12:00 10 1
20:50:00 10 0
08:01:30 15 1
20:53:00 10 1
3 1
2
输出样例:
08:00:00 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:12:00 08:16:30 5
08:10:00 08:20:00 10
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0
3 3 2
1026 Table Tennis (30 point(s))
A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the tables are occupied, they will have to wait in a queue. It is assumed that every pair of players can play for at most 2 hours.
Your job is to count for everyone in queue their waiting time, and for each table the number of players it has served for the day.
One thing that makes this procedure a bit complicated is that the club reserves some tables for their VIP members. When a VIP table is open, the first VIP pair in the queue will have the privilege to take it. However, if there is no VIP in the queue, the next pair of players can take it. On the other hand, if when it is the turn of a VIP pair, yet no VIP table is available, they can be assigned as any ordinary players.
Input Specification:
Each input file contains one test case. For each case, the first line contains an integer N (≤10000) - the total number of pairs of players. Then N lines follow, each contains 2 times and a VIP tag: HH:MM:SS - the arriving time, P - the playing time in minutes of a pair of players, and tag - which is 1 if they hold a VIP card, or 0 if not. It is guaranteed that the arriving time is between 08:00:00 and 21:00:00 while the club is open. It is assumed that no two customers arrives at the same time. Following the players info, there are 2 positive integers: K (≤100) - the number of tables, and M (< K) - the number of VIP tables. The last line contains M table numbers.
Output Specification:
For each test case, first print the arriving time, serving time and the waiting time for each pair of players in the format shown by the sample. Then print in a line the number of players served by each table. Notice that the output must be listed in chronological order of the serving time. The waiting time must be rounded up to an integer minute(s). If one cannot get a table before the closing time, their information must NOT be printed.
思路:
把 Player 和 Table 分别放到四个优先队列里面 VIP Player VIP Table normal Player normal Table 把所有 Player 放入相应的优先队列,被分配了就把 Player 弹出来,被分配到的 Table 也弹出来,更新结束时间,再放入 Table 对应的源码下载队列 关键时间点全靠堆顶输出 因此退出循环的依据有两个:Player 空了,或者没有 Table 在 21:00 前结束 桌子分配原则: 如果轮到 VIP Player 并且 VIP Table 有空缺,则分配; 如果轮到 normal Player 并且只有 VIP Table 有空缺,分配; 如果轮到 VIP Player 并且只有 VIP Table 有空缺,分配; 其他情况分配 normal Player注意事项:
往各个优先队列输入 INF 的时间原始,且保证其永远不会到达堆顶,这样不用判断是不是空节点 每次四个优先队列都出队堆顶,方便书写 对于每个玩家关键时间点 cur_time ,如果有桌子的 end_time 比这个小,则更新 end_time 为这个 cur_time ,防止后面漏判空余桌子 #include <iostream> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <cmath> using namespace std; const int N = 1e4 + 10, M = 1e2 + 10, INF = 2e9; int n, k, m; struct Player { int arrive_time, serve_time; int start_time, waiting_time; // 给 sort 排 const bool operator< (const Player& t) const { if (start_time != t.start_time) return start_time < t.start_time; return arrive_time < t.arrive_time; } // 给 priority_queue 排 const bool operator> (const Player& t) const { return arrive_time > t.arrive_time; } }; struct Table { int id; int end_time; const bool operator> (const Table& t) const { if (end_time != t.end_time) return end_time > t.end_time; return id > t.id; } }; bool is_vip_table[M]; int table_count[M]; // 最终输出的玩家及顺序 vector<Player> players; // 注意 `&` 很重要 void assign(priority_queue<Player, vector<Player>, greater<Player>>& ps, priority_queue<Table, vector<Table>, greater<Table>>& ts) { auto p = ps.top(); ps.pop(); auto t = ts.top(); ts.pop(); int start_time = t.end_time; int end_time = start_time + p.serve_time; ts.push({ t.id, end_time}); table_count[t.id] ++; p.start_time = start_time; p.waiting_time = round((start_time - p.arrive_time) / 60.0); players.push_back(p); } string time_to_string(int sec) { char str[20]; sprintf(str, "%02d:%02d:%02d", sec / 3600, sec % 3600 / 60, sec % 60); return str; } int main() { // 输入玩家 priority_queue<Player, vector<Player>, greater<Player>> normal_players; priority_queue<Player, vector<Player>, greater<Player>> vip_players; normal_players.push({ INF}); vip_players.push({ INF}); cin >> n; for (int i = 0; i < n; i ++ ) { int hour, minute, sec; int serve_time, is_vip; scanf("%d:%d:%d %d %d", &hour, &minute, &sec, &serve_time, &is_vip); sec = hour * 3600 + minute * 60 + sec; serve_time = min(serve_time * 60, 7200); if (is_vip) vip_players.push({ sec, serve_time}); else normal_players.push({ sec, serve_time}); } // 输入桌子 priority_queue<Table, vector<Table>, greater<Table>> normal_tables; priority_queue<Table, vector<Table>, greater<Table>> vip_tables; normal_tables.push({ -1, INF}); vip_tables.push({ -1, INF}); cin >> k >> m; for (int i = 0; i < m; ++ i) { int id; cin >> id; is_vip_table[id] = true; } for (int i = 1; i <= k; i ++ ) { if (is_vip_table[i]) vip_tables.push({ i, 8 * 3600}); else normal_tables.push({ i, 8 * 3600}); } // 开始分配 while (normal_players.size() > 1 || vip_players.size() > 1) { auto np = normal_players.top(); auto vp = vip_players.top(); int cur_time = min(np.arrive_time, vp.arrive_time); while (normal_tables.top().end_time < cur_time) { auto t = normal_tables.top(); normal_tables.pop(); t.end_time = cur_time; normal_tables.push(t); } while (vip_tables.top().end_time < cur_time) { auto t = vip_tables.top(); vip_tables.pop(); t.end_time = cur_time; vip_tables.push(t); } auto nt = normal_tables.top(); auto vt = vip_tables.top(); int end_time = min(nt.end_time, vt.end_time); if (end_time >= 21 * 3600) break; if (vp.arrive_time <= end_time && vt.end_time == end_time) assign(vip_players, vip_tables); else if (np.arrive_time < vp.arrive_time) { if (nt > vt) assign(normal_players, vip_tables); else assign(normal_players, normal_tables); } else { if (nt > vt) assign(vip_players, vip_tables); else assign(vip_players, normal_tables); } } sort(players.begin(), players.end()); for (auto p: players) { cout << time_to_string(p.arrive_time) << " " << time_to_string(p.start_time) << " " << p.waiting_time << endl; } for (int i = 1; i <= k; i ++ ) { cout << table_count[i]; if (i + 1 <= k) cout << " "; else cout << endl; } }很赞哦!(28671)
相关文章
- cm域名有什么独特之处?新人要了解cm域名哪些?
- 多集群Kubernetes管理解决方案
- VR用户大调查:VR比体感游戏主机更好玩?
- Java编程内功-数据结构与算法「稀疏数组」
- 前面这两个步骤都是在本机完成的。到这里还没有涉及真正的域名解析服务器,如果在本机中仍然无法完成域名的解析,就会真正请求域名服务器来解析这个域名了。
- 程序员如何掌握Bug生产之术?
- 都说HashMap是线程不安全的,到底体现在哪儿?
- 企业应用的转折点:内存计算技术
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- 一篇文章教会你Python访问限制那些事儿