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(Advanced Level)Practice--1026(Table Tennis)