• 1026 Table Tennis


    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.


    Sample Input:

    1. 10
    2. 20:52:00 10 0
    3. 08:00:00 20 0
    4. 08:02:00 30 0
    5. 20:51:00 10 0
    6. 08:10:00 30 0
    7. 08:12:00 10 1
    8. 20:40:00 13 0
    9. 08:01:30 15 1
    10. 20:53:00 10 1
    11. 20:54:00 10 0
    12. 3 1
    13. 2

    Sample Output:

    1. 08:00:00 08:00:00 0
    2. 08:01:30 08:01:30 0
    3. 08:02:00 08:02:00 0
    4. 08:12:00 08:16:30 5
    5. 08:10:00 08:20:00 10
    6. 20:40:00 20:40:00 0
    7. 20:51:00 20:51:00 0
    8. 20:52:00 20:52:00 0
    9. 20:53:00 20:53:00 0
    10. 4 3 2

    题目大意

    桌球俱乐部有N张桌子,其中有M张是VIP桌子。对于所有普通的桌子,先到先得。对于VIP桌子,VIP人员有特殊待遇,但如果在场无等待游玩的VIP人员,VIP桌子可为普通人员服务。但如果排队等待的人员中,有VIP人员,VIP桌子优先提供给最先抵达的VIP人员。

    注意 : VIP人员优先使用VIP桌子,但如果他抵达时,VIP桌子没有空,但普通桌子有空,其亦可正常排队,去使用普通桌子。

    求每个人开始游玩的时间,和等待时间,最后输出每桌服务的人数


    思路

    为人员建立一个数据结构,ed[n]表示窗口n最后结束工作的时间

    setvip,记录VIP窗口的编号,对VIP窗口的使用进行分类讨论即可


    C/C++ 

    1. #include
    2. using namespace std;
    3. struct Player{
    4. int arrive,start,play,vip;
    5. }p;
    6. set<int> vip;
    7. vector line[2],all;
    8. int ed[101]={999999},nums[101],edNum,N;
    9. bool cmp1(Player x,Player y){ return x.arrive>y.arrive; }
    10. Player earlyArrive();
    11. bool findTable();
    12. int main()
    13. {
    14. int a,b,c;
    15. cin >> N;
    16. while (N--){
    17. scanf("%d:%d:%d %d %d", &a, &b, &c, &p.play, &p.vip);
    18. p.arrive = a * 3600 + b * 60 + c;
    19. if (p.arrive >= 75600) continue;
    20. if (p.play > 120) p.play = 120;
    21. line[p.vip].push_back(p);
    22. }
    23. cin >> edNum >> N;
    24. while (N--){
    25. cin >> a;
    26. vip.insert(a);
    27. }
    28. sort(line[0].begin(),line[0].end(), cmp1);
    29. sort(line[1].begin(),line[1].end(), cmp1);
    30. while (!line[0].empty() || !line[1].empty()){
    31. p = earlyArrive();
    32. if(!findTable()) break;
    33. }
    34. for(Player x:all){
    35. int num1 = x.arrive,num2 = x.start;
    36. printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",num1/3600,num1%3600/60,num1%60,num2/3600,num2%3600/60,num2%60,(num2-num1+30)/60);
    37. }
    38. cout << nums[1];
    39. for(int z=2;z<=edNum;z++) cout << " " << nums[z];
    40. return 0;
    41. }
    42. bool findTable()
    43. {
    44. if(p.vip==1){ // vip优先匹配VIP窗口
    45. for(int x:vip){
    46. if(ed[x]<=p.arrive){
    47. p.start = p.arrive;
    48. ed[x] = p.arrive + p.play*60;
    49. all.push_back(p);
    50. line[1].pop_back();
    51. nums[x]++;
    52. return true;
    53. }
    54. }
    55. }
    56. int flag = 0; // 找到该人抵达时,已经完成工作的最小编号窗口
    57. for(int z=1;z<=edNum;z++){
    58. if(ed[z]
    59. flag = z;
    60. break;
    61. }
    62. }
    63. if(flag==0) for(int z=1;z<=edNum;z++) if(ed[z]// 该人抵达时,没有空窗口,那就寻找最先结束的窗口
    64. if(ed[flag]>=75600) return false;
    65. for(int x:vip){
    66. if(line[1].empty()) break;
    67. if(flag==x){
    68. if(ed[flag]>=line[1].back().arrive) p = line[1].back();
    69. break;
    70. }
    71. }
    72. nums[flag]++;
    73. if(ed[flag]<=p.arrive){
    74. p.start = p.arrive;
    75. ed[flag] = p.arrive + p.play*60;
    76. }else{
    77. p.start = ed[flag];
    78. ed[flag] += p.play*60;
    79. }
    80. all.push_back(p);
    81. line[p.vip].pop_back();
    82. return true;
    83. }
    84. Player earlyArrive()
    85. {
    86. if(line[1].empty() || (!line[0].empty() && line[1].back().arrive > line[0].back().arrive)) return line[0].back();
    87. return line[1].back();
    88. }


     

  • 相关阅读:
    kafka怎么实现零拷贝(Zero-Copy)的?
    Android绘图学习(一)
    Mysql---第八篇
    IDEA更换新版本启动没反应
    Gitea—私有git服务器搭建教程
    搭建个人知识付费应用系统整体需求及详细设计
    记录第一次给开源项目提 PR
    五矿集团params逆向分析
    Rust常见编程概念
    Docker 部署本地爬虫项目到服务器
  • 原文地址:https://blog.csdn.net/daybreak_alonely/article/details/127712764