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 priviledge 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.

Sample Input:

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

Sample Output:

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

先理清题目中重要的点:
把所有的时间都转换成秒方便比较。
1.playing time最多是120(两小时),超过的按照120处理
2.对于vip客户,先查看是否有空闲的vip桌,如果有选择编号最小的,如果没有按照普通客户来处理
3.当前处理的客户没有空闲桌子时需要等待最先空闲的一个桌子,如果最先空闲的桌子是个vip桌,而此客户又不是vip客户,那么要查看后到的客户中是否有vip客户,且vip客户到达时间在vip桌空闲时间之前,如果有,就先处理此vip客户。同时要重新处理当前非vip客户。
4.结果等待时间需要四舍五入。
5.到达时间没有重复的,可以按到达时间排序。
6.营业时间截止21点,处理时间超过21点的就违反了规定,不输出。
每处理一个客户就输出一个客户。
#include <stdlib.h>
#include <stdio.h>
#define inf 0x3f3f3f3f
#define MAX 10001 const int e = * ;
/**
n个乒乓球桌 1-n
每对players选择open的编号最小的 没有open的就排队
最多play两小时
计数每对的等待时间 每桌的服务次数
对于vip桌 第一对vip 可以用 如果队里没有vip 那么可以当成一般的给一般的一对plays用
如果没有vip桌了 可以给vip普通桌
不会有重复的到达时间
**/
struct player {
int t,p,tag,ser;
}pl[MAX];
struct table {
int ifvip,num,t;
}ta[];
int n,hh,mm,ss,p,tag,k,m,d,vis[MAX];///vis标记是否处理过
int simplify(int hh,int mm,int ss) {///时间化为秒
return hh * + mm * + ss;
}
int cmp(const void *a,const void *b) {
return ((struct player *)a) -> t - ((struct player *)b) -> t;
}
int max(int a,int b) {
return a > b ? a : b;
}
int havevip(int a,int b) {///等待a号桌的人中是否有vip 如果有返回编号 没有就返回-1
while(++ b < n) {
if(!vis[b] && pl[b].tag) {
if(pl[b].t < ta[a].t)return b;
return -;
}
}
return -;
}
int main() {
scanf("%d",&n);
for(int i = ;i < n;i ++) {
scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&pl[i].p,&pl[i].tag);
pl[i].t = simplify(hh,mm,ss);
if(pl[i].p > )pl[i].p = ;///play超过120
pl[i].p *= ;///化成秒
}
scanf("%d%d",&k,&m);
for(int i = ;i < m;i ++) {
scanf("%d",&d);
ta[d].ifvip = ;
}
for(int i = ;i <= k;i ++) {
ta[i].num = ta[i].t = ;
}
qsort(pl,n,sizeof(struct player),cmp);///按到达时间排序
for(int i = ;i < n;i ++) {
if(vis[i])continue;
int ti = -,mi = inf;
if(pl[i].tag)///vip客户先查看是否有空的vip桌子 没有就当成一般客户对待
for(int j = ;j <= k;j ++) {///按编号从小到大查看 如果有空桌子 ti就不再是-1
if(ta[j].ifvip && ta[j].t <= pl[i].t) {
ti = j;
mi = ta[j].t;
break;
}
}
if(ti == -)
for(int j = ;j <= k;j ++) {///按编号从小到大查看 如果有空的 直接用
if(ta[j].t <= pl[i].t) {///不用排队
ti = j;
mi = ta[j].t;
break;
}
else if(ta[j].t < mi) {///需要排队,找到最先空闲的桌子
ti = j;
mi = ta[j].t;
}
}
if(mi > pl[i].t && ta[ti].ifvip && !pl[i].tag) {///需要排队且最先空闲的桌子是vip而当前客户非vip
d = havevip(ti,i);
if(d != -) {///队伍里有vip客户
if((pl[d].ser = mi) >= e)break;
i --;///要重新处理当前非vip客户
ta[ti].t = pl[d].ser + pl[d].p;
ta[ti].num ++;
int w = max(,pl[d].ser - pl[d].t);
vis[d] = ;
printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",pl[d].t / ,pl[d].t / % ,pl[d].t % ,pl[d].ser / ,pl[d].ser / % ,pl[d].ser % ,(w + ) / );///四舍五入
continue;
}
}
if((pl[i].ser = max(mi,pl[i].t)) >= e)break;
ta[ti].t = pl[i].ser + pl[i].p;
ta[ti].num ++;
int w = max(,pl[i].ser - pl[i].t);
vis[i] = ;
printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",pl[i].t / ,pl[i].t / % ,pl[i].t % ,pl[i].ser / ,pl[i].ser / % ,pl[i].ser % ,(w + ) / );///四舍五入
}
for(int i = ;i <= k;i ++) {///输出每个桌服务人数
if(i > )putchar(' ');
printf("%d",ta[i].num);
}
}

1026 Table Tennis (30)(30 分)的更多相关文章

  1. PAT 甲级 1026 Table Tennis (30 分)(坑点很多,逻辑较复杂,做了1天)

    1026 Table Tennis (30 分)   A table tennis club has N tables available to the public. The tables are ...

  2. PAT 1026 Table Tennis[比较难]

    1026 Table Tennis (30)(30 分) A table tennis club has N tables available to the public. The tables ar ...

  3. PAT甲级1026. Table Tennis

    PAT甲级1026. Table Tennis 题意: 乒乓球俱乐部有N张桌子供公众使用.表的编号从1到N.对于任何一对玩家,如果有一些表在到达时打开,它们将被分配给具有最小数字的可用表.如果所有的表 ...

  4. PAT 甲级 1026 Table Tennis(模拟)

    1026. Table Tennis (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A table ...

  5. 1026 Table Tennis (30分)

    A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For a ...

  6. 1026 Table Tennis (30分) 难度不高 + 逻辑复杂 +细节繁琐

    题目 A table tennis club has N tables available to the public. The tables are numbered from 1 to N. Fo ...

  7. 1026. Table Tennis (30)

    题目如下: A table tennis club has N tables available to the public. The tables are numbered from 1 to N. ...

  8. PAT A1026 Table Tennis (30 分)——队列

    A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For a ...

  9. PAT 1026 Table Tennis (30)

    A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For a ...

随机推荐

  1. js new一个函数和直接调用函数的差别

    用new和调用一个函数的差别:假设函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象.而假设这个函数的返回值是一个引用类型(Object.Arr ...

  2. UVA 10428 - The Roots(牛顿迭代法)

    UVA 10428 - The Roots option=com_onlinejudge&Itemid=8&page=show_problem&category=494& ...

  3. 获取网站的BaseURL

    //get base URL            var _urlstr = window.location.href;            if (_urlstr.indexOf("? ...

  4. 自动关闭AfxMessageBox对话框―模拟"回车" VC

    有的时候,在程序里面调用太多的AfxMessageBox(非调试用),弹出的对话框要手动关闭,时间一长就感觉很繁琐.于是上网找了一些资料,发现有一个很简单的实现AfxMessageBox对话框自动关闭 ...

  5. 数据结构与算法之枚举(穷举)法 C++实现

    枚举法的本质就是从全部候选答案中去搜索正确的解,使用该算法须要满足两个条件: 1.能够先确定候选答案的数量. 2.候选答案的范围在求解之前必须是一个确定的集合. 枚举是最简单.最基础.也是最没效率的算 ...

  6. 50道JAVA基础编程练习题 - 题目

    50道JAVA基础编程练习题[1]题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [2]题目:判断 ...

  7. MessageDigest和DigestUtils加密算法

    总结:使用DigestUtils的方法加密的结果与messageDigest的方法加密结果一致,可使用DigestUtils替换MessageDigest 可省掉部分代码  package com.a ...

  8. C#中GroupBox控件的使用(转)

    GroupBox(框架)控件是C#中用来组织其他控件形成一个控件组,它的使用方法为[工具箱]->[所有Windows窗体](或者是[容器]列表中)->[GroupBox],拖拽到窗体界面中 ...

  9. CSS浏览器兼容性问题解决方法总结

    CSS浏览器兼容解决总结如下: 1. CSS中几种浏览器对不同关键字的支持,可进行浏览器兼容性重复定义 !important 可被FireFox和IE7识别 * 可被IE6.IE7识别 _ 可被IE6 ...

  10. 我的Android进阶之旅------>Android中ListView中嵌套(ListView)控件时item的点击事件不起作的问题解决方法

    开发中常常需要自己定义Listview,去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点. 如果你的自定义Li ...