PAT甲级1026 Table Tennis【模拟好题】

题目https://pintia.cn/problem-sets/994805342720868352/problems/994805472333250560

题意:

有k张乒乓球桌,有的是vip桌。有n对玩家来打乒乓,有的玩家是VIP玩家。

当他们到达时,如果没有空桌子他们就排队等待。

这时候如果有VIP桌子空出来了,那么就优先给队列里的VIP玩家,如果没有VIP玩家就给普通玩家。

如果普通桌子空出来了,就给队列里排在最前的玩家。

如果玩家到达的时候有好多桌子可以选择,那么他会选择桌号最小的那张,VIP玩家会优先选择桌号最小的VIP桌子【这题意真的....】

每对玩家最多只能玩两个小时。

营业时间是上午八点到晚上九点。如果在晚上九点还没开始玩就不能玩了。

最后输出每对玩家到达时间,开始玩的时间和(四舍五入后的)等待时间。

思路:

我好菜系列。PAT真是练模拟的好地方。

首先根据输入把时间按照秒预处理。然后把所有玩的时间超过2小时的设置为2小时。

建两个玩家队列,把VIP玩家和非VIP玩家分开,分别遍历直到两个队列都为空。

对于队首的VIP玩家和非VIP玩家我们先根据他们到达的最早时间找到一张合法的桌子(不管是VIP桌还是非VIP桌)table1

然后我们再根据VIP玩家到达的时间找到桌号最小的VIP桌。table2

找的过程是:如果当前桌子的结束时间小于当前时间,那么break,如果找不到小于的就要在大于之中找到结束时间最早的一张桌子。

之后我们判断到底是VIP玩家先玩还是非VIP玩家先玩。

如果非VIP到的比VIP早,并且table1的结束时间比VIP到达的早,那么非VIP先玩。

如果非VIP到的比VIP早,并且table1不是VIP桌,那么非VIP也先玩。

否则就是VIP先玩。

如果是VIP先玩,那么他应该要选择合法的桌号最小的VIP桌,也就是table2

然后更新这对玩家的时间还有桌子的结束时间和数量。根据是谁玩的,决定是哪个队列的下标+1.

由于有的玩家玩不到了,所以每对玩家还需要用一个vis标记是否玩了。

四舍五入可以适用round()函数。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<map>
  4 #include<set>
  5 #include<iostream>
  6 #include<cstring>
  7 #include<algorithm>
  8 #include<vector>
  9 #include<cmath>
 10 #include<stack>
 11 #include<queue>
 12
 13 #define inf 0x7fffffff
 14 using namespace std;
 15 typedef long long LL;
 16 typedef pair<string, string> pr;
 17
 18 int n;
 19 const int maxn = 1e4 + 5;
 20 int k, m;
 21 int cnt[105];
 22
 23 struct player{
 24     int id;
 25     int arrive_time;
 26     int play_time;
 27     bool vip;
 28     int serve_time = 0;
 29     int wait;
 30     bool can = false;
 31 }peo[maxn];
 32
 33 struct table{
 34     int id;
 35     int finish_time = 0;
 36     bool vip = false;
 37     bool operator < (table b)const{
 38         if(finish_time == b.finish_time)return id > b.id;
 39         return finish_time > b.finish_time;
 40     }
 41 }tab[105];
 42
 43 bool cmp(player a, player b)
 44 {
 45     return a.arrive_time < b.arrive_time;
 46 }
 47
 48 bool cmp1(player a, player b)
 49 {
 50     return a.arrive_time + a.wait < b.arrive_time + b.wait;
 51 }
 52
 53 int findd(int t, int type)
 54 {
 55     int ret = 1000000, ans = 0;
 56     for(int i = 1; i <= k; i++){
 57         if(type && !tab[i].vip)continue;
 58         if(tab[i].finish_time < t){
 59             ans = i;
 60             break;
 61         }
 62         else if(tab[i].finish_time < ret){
 63             ans = i;
 64             ret = tab[i].finish_time;
 65         }
 66     }
 67     return ans;
 68 }
 69
 70 vector<player>que[2];
 71 int main()
 72 {
 73     scanf("%d", &n);
 74     for(int i = 1; i <= n; i++){
 75         int h, m, s;
 76         peo[i].id = i;
 77         scanf("%d:%d:%d %d %d", &h, &m, &s, &peo[i].play_time, &peo[i].vip);
 78         peo[i].arrive_time = (h - 8) * 60 * 60 + m * 60 + s;
 79         if(peo[i].play_time > 120)peo[i].play_time = 120;
 80         peo[i].play_time *= 60;
 81         que[peo[i].vip].push_back(peo[i]);
 82     }
 83     peo[n + 1].arrive_time = peo[n + 2].arrive_time = 1e8;
 84     que[0].push_back(peo[n + 1]);
 85     que[1].push_back(peo[n + 2]);
 86     scanf("%d %d", &k, &m);
 87     for(int i = 0; i < m; i++){
 88         int t;
 89         scanf("%d", &t);
 90         tab[t].vip = true;
 91     }
 92
 93     sort(que[0].begin(), que[0].end(), cmp);
 94     sort(que[1].begin(), que[1].end(), cmp);
 95     int i = 0, j = 0, num = 0;
 96     while(1){
 97         int time1 = que[0][i].arrive_time, time2 = que[1][j].arrive_time;
 98         int tableid = findd(min(time1, time2), 0);
 99         int viptab = findd(time2, 1);
100         if(tab[tableid].finish_time >= 13 * 60 *60 || min(time1, time2) >= 13 * 60 * 60)break;
101         int who;
102         if(tab[tableid].vip == 0)who = (time1 < time2)?0:1;
103         else who = (max(tab[tableid].finish_time, time1) > time2)?1:0;
104         if(who && viptab && tab[viptab].finish_time <= time2)tableid = viptab;
105         int peoid = (who == 0)?que[0][i].id:que[1][j].id;
106         peo[peoid].serve_time = max(tab[tableid].finish_time, peo[peoid].arrive_time);
107         peo[peoid].wait = peo[peoid].serve_time - peo[peoid].arrive_time;
108         tab[tableid].finish_time = peo[peoid].serve_time + peo[peoid].play_time;
109         cnt[tableid]++;
110         peo[peoid].can = true;
111         if(who)j++;
112         else i++;
113         //num++;
114     }
115
116     sort(peo + 1, peo + 1 + n, cmp1);
117     for(int i = 1; i <= n; i++){
118         if(peo[i].wait < 0)peo[i].wait = 0;
119         if(!peo[i].can)continue;
120         int h, m, s;
121         h = peo[i].arrive_time / (60 * 60) + 8;
122         m = peo[i].arrive_time % (60 * 60);
123         m = m / 60;
124         s = peo[i].arrive_time % 60;
125         printf("%02d:%02d:%02d ", h, m, s);
126         h = (peo[i].arrive_time + peo[i].wait) / (60 * 60) + 8;
127         m = (peo[i].arrive_time + peo[i].wait) % (60 * 60);
128         m = m / 60;
129         s = (peo[i].arrive_time + peo[i].wait) % 60;
130         printf("%02d:%02d:%02d ", h, m, s);
131         //cout<<(peo[i].wait + 30) / 60<<endl;
132         cout<<round(1.0 * peo[i].wait / 60.0)<<endl;
133         //printf("%d\n", round(1.0 * peo[i].wait / 60.0));
134
135     }
136     printf("%d", cnt[1]);
137     for(int i = 2; i <= k; i++){
138         printf(" %d", cnt[i]);
139     }
140     printf("\n");
141     return 0;
142 }

原文地址:https://www.cnblogs.com/wyboooo/p/10453017.html

时间: 2024-11-08 13:38:36

PAT甲级1026 Table Tennis【模拟好题】的相关文章

1026 Table Tennis (30 分)

1026 Table Tennis (30 分) 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 sma

浙大 PAT Advanced level 1026. Table Tennis (30)

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

1026. Table Tennis (30)

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

PAT (Advanced Level) 1026. Table Tennis (30)

情况比较多的模拟题. 交了50发的样子才AC......AC之后我的天空星星都亮了. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<map> #include<queue> #include<vector> using namespace std; struct

Pat(Advanced Level)Practice--1026(Table Tennis)

Pat1026代码 题目描写叙述: 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 n

PAT甲级题分类汇编——线性

线性类,指线性时间复杂度可以完成的题.在1051到1100中,有7道: 题号 标题 分数 大意 时间 1054 The Dominant Color 20 寻找出现最多的数 200ms 1061 Dating 20 寻找字符串中相同字符 200ms 1071 Speech Patterns 25 寻找出现最多的单词 300ms 1077 Kuchiguse 20 字符串共同后缀 150ms 1082 Read Number in Chinese 25 中文读数 400ms 1084 Broken

PAT甲级题分类汇编——理论

理论这一类,是让我觉得特别尴尬的题,纯粹是为了考数据结构而考数据结构.看那Author一栏清一色的某老师,就知道教数据结构的老师的思路就是和别人不一样. 题号 标题 分数 大意 Author 1051 Pop Sequence 25 判断一个序列是否是pop序列 CHEN, Yue 1052 Linked List Sorting 25 链表排序 CHEN, Yue 1057 Stack 30 一个有中位数功能的stack CHEN, Yue 1074 Reversing Linked List

PAT甲级考前整理

终于在考前,刷完PAT甲级130道题目,不容易!!!每天沉迷在刷题之中而不能超脱,也是一种境界.PAT甲级题目总的说卡题目的比较多,卡测试点的比较少,有些题目还会有题意混淆,这点就不吐槽了吧.静下心来耍这130道题,其实磨练的是一种态度与手感,养成的是一种习惯.热爱AC没有错!! 130道题目主要的考点: 1.排序:快速排序,直接插入排序,希尔排序,分治排序,堆排序. 2.图论:拓扑排序.最短路径.深度搜索.广度搜索. 3.树:树的遍历.完全二叉树.AVL. 4.其他:并查集,模拟,哈希.背包.

PAT甲级1005 Spell It Right

题目:PAT甲级 1005 题解:水题.看到题目的第一时间就在想一位一位的mod,最后一加一转换就完事了.结果看到了N最大为10的100的次方,吓得我赶紧放弃这个想法... 发现碰到这种情况用字符串十分好用,这道题应该考察的就是这一点.大致思路就是把数字的每一位放到字符串中,然后通过ASCII码得到每一位的相加结果num,然后把num一位一位的放到stack中,使用stack是因为它先进先出的特性,最后输出就行了. 代码: 1 #include<cstdio> 2 #include<qu