pat1026Table Tennis (30)

56 篇文章 0 订阅

题意分析:

(1)给出N个人到达乒乓球场的时间以及他们需要打多长时间的球,这些人分为两类:一类是VIP客户,一类是非VIP客户,所有的客户按到来的时间排好队伍等候,一旦出现空的乒乓球台,客户将立即选择编号最小的乒乓球台,每个客户最多不能超过两个小时,求每个客户的等待时间,以及每个乒乓球台一天服务了多少人。

(2)VIP客户与普通客户不同点在于:一旦有VIP桌子空闲,处于等待队列中的最早到达的VIP客户(如果有的话)可以获得使用权,而不管他前面是否有人在等待。

(3)如果没有VIP客户,当VIP卓空闲时,普通客户也可使用。

(4)综上所述,需要维护三个队列:VIP客户到达时间的序列、普通用户到达时间的序列、每个桌子空闲的时刻,其中桌子的空闲时刻的计算跟1017题银行窗口空闲时刻的计算一样,大家可以去参考。

(5)这三个队列的更新策略是:一旦有桌子空闲,在队列中最早到达的人可以选择序号最小的空闲的桌子使用;有以下情况例外:若此桌是VIP桌子,且队列中有VIP等待客户,那么无论他前面是否还有等待的人,立即获得使用权;还有若既有普通桌子和VIP桌子空闲,VIP客户选择VIP桌子

可能坑点:

这题难倒了不少人,题干中有几处没有说明白(大坑!!!),其中也是巨坑连连。。。,总结起来有以下几点需要注意:

(1)每个乒乓球台的服务时间在8:00~21:00之间,超过21:00的不再服务
(2)等待队列中,VIP的优先级体现在当有空VIP专用球台时,VIP客户可以直接使用,而不管前面是否有普通客户在等待
(3)最为重要的一点,当有普通球台和VIP球台时,VIP客户遵循选择最小编号的VIP球台(VIP就要这么任性),而非编号最小的球台;普通客户遵循选择最小的球台
(4)每个人的服务时间在2小时之内,超过2小时的按2小时处理;
(5)注意最后计算等待时间时采用的是四舍五入

#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <limits.h>
using namespace std;

struct players
{
    int arriveTime;
    int startServe;
    int serveTime;
    int waitTime;
    int isVIP;
};
//等待队列中的VIP客户
vector<players >vipPlayers;
//普通客户
vector<players >ordinaryPlayers;
//处理完输出信息的客户
vector<players >total;
struct tables
{
    int VIP;
    int cnt;
    int vacantTime;
};
tables t[101];

bool cmpPlayers(players a,players b)
{
    return a.arriveTime<b.arriveTime;
}

bool cmpStartServe(players a,players b)
{
    return a.startServe<b.startServe;
}

int main()
{
    int N,K,M,i=0;
    cin>>N;
    int hh,mm,ss,wait,vip;
    players temp;
    while(i<N)
    {
        scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&wait,&vip);
        temp.arriveTime=hh*3600+mm*60+ss;
        temp.serveTime=wait*60;
        temp.isVIP=vip;
        i++;
        if(temp.arriveTime>=3600*21)continue;
        if(vip==1)vipPlayers.push_back(temp);
        else ordinaryPlayers.push_back(temp);
    }
    cin>>K>>M;
    for(int j=1;j<=K;j++)
    {
        t[j].VIP=0;
        t[j].vacantTime=8*3600;
        t[j].cnt=0;
    }
    int tag;
    for(int j=0;j<M;j++)
    {
        cin>>tag;
        t[tag].VIP=1;
    }

    if(ordinaryPlayers.size()>0)sort(ordinaryPlayers.begin(),ordinaryPlayers.end(),cmpPlayers);
    if(vipPlayers.size()>0)sort(vipPlayers.begin(),vipPlayers.end(),cmpPlayers);

    while(ordinaryPlayers.size()>0||vipPlayers.size()>0)
    {
        int minVacant=INT_MAX;
        int minVipVacant=INT_MAX;
        int index;
        int vipIndex;
        for(int j=1;j<=K;j++)
        {
            if(t[j].vacantTime<minVacant)
            {
                minVacant=t[j].vacantTime;
                index=j;
            }
            if(t[j].VIP==1&&t[j].vacantTime<minVipVacant)
            {
                minVipVacant=t[j].vacantTime;
                vipIndex=j;
            }
        }
        if(t[index].vacantTime>=21*3600)break;
        players nextPlayers;
        if(vipPlayers.size()==0)
        {
            nextPlayers=ordinaryPlayers.front();
            ordinaryPlayers.erase(ordinaryPlayers.begin());
        }
        else if(ordinaryPlayers.size()==0)
        {
            nextPlayers=vipPlayers.front();
            vipPlayers.erase(vipPlayers.begin());
        }
        else
        {
            if(t[index].VIP==1)
            {
                if(vipPlayers.front().arriveTime<ordinaryPlayers.front().arriveTime||t[index].vacantTime>=vipPlayers.front().arriveTime)
                {
                    nextPlayers=vipPlayers.front();
                    vipPlayers.erase(vipPlayers.begin());
                }
                else
                {
                    nextPlayers=ordinaryPlayers.front();
                    ordinaryPlayers.erase(ordinaryPlayers.begin());
                }
            }
            else
            {
                if(vipPlayers.front().arriveTime<ordinaryPlayers.front().arriveTime)
                {
                    nextPlayers=vipPlayers.front();
                    vipPlayers.erase(vipPlayers.begin());
                }
                else
                {
                    nextPlayers=ordinaryPlayers.front();
                    ordinaryPlayers.erase(ordinaryPlayers.begin());
                }
            }
        }
        //控制每个人的时间在两小时之内,超过两小时按两个小时截断
        if(nextPlayers.serveTime>7200)nextPlayers.serveTime=7200;
        //这里需要记清楚:一旦有VIP桌子空闲,等待队列中的VIP客户就会选择VIP桌子,不管是否有普通桌子空闲
        if(nextPlayers.isVIP==1&&nextPlayers.arriveTime>=t[vipIndex].vacantTime)
        {
            nextPlayers.waitTime=0;
            nextPlayers.startServe=nextPlayers.arriveTime;
            t[vipIndex].vacantTime=nextPlayers.arriveTime+nextPlayers.serveTime;
            t[vipIndex].cnt++;
        }
        else
        {
            if(nextPlayers.arriveTime<=t[index].vacantTime)
            {
                nextPlayers.waitTime=t[index].vacantTime-nextPlayers.arriveTime;
                nextPlayers.startServe=t[index].vacantTime;
                t[index].vacantTime+=nextPlayers.serveTime;
            }
            else
            {
                nextPlayers.waitTime=0;
                nextPlayers.startServe=nextPlayers.arriveTime;
                t[index].vacantTime=nextPlayers.arriveTime+nextPlayers.serveTime;
            }
            t[index].cnt++;
        }
        total.push_back(nextPlayers);
    }
    sort(total.begin(),total.end(),cmpStartServe);
    for(int i=0;i<total.size();i++)
    {
        int waitMinutes=total[i].waitTime/60+(total[i].waitTime%60<30?0:1);
        printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",total[i].arriveTime/3600,
               (total[i].arriveTime%3600)/60,total[i].arriveTime%60,
               total[i].startServe/3600,(total[i].startServe%3600)/60,
               total[i].startServe%60,waitMinutes);
    }
    int first=1;
    for(int i=1;i<=K;i++)
    {
        if(first)first=0;
        else cout<<" ";
        cout<<t[i].cnt;
    }
    return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值