PAT甲级1026 Table Tennis模拟好题

Posted wyboooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
", 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("
");
141     return 0;
142 }

 

以上是关于PAT甲级1026 Table Tennis模拟好题的主要内容,如果未能解决你的问题,请参考以下文章

PAT 1026 Table Tennis

PAT 1026. Table Tennis

PAT 1026 Table Tennis[比较难]

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

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

1026 Table Tennis (30 分) 未完成难度: 难 / 知识点: 模拟