甲级PAT 1014 Waiting in Line (30 分)(模拟)

【题解】

甲级凡是有问题,大多出在读题。

题意:有n个窗口,每个窗口黄线内可以排长度为m个人的队,总共有k个客户,每个客户有一个解决时间ti,q个询问,每次询问编号为x的客户在几点办完事情。

思路:我们看到,一天的工作时间是从8:00-17:00,共9个小时9*60=540分钟,数据比较小所以我们选择按时间枚举没有疑问。根据题目中的举例,我们可以看到,当黄线内没有满的时间,客户会优先选择队伍比较短窗口编号比较小的窗口进行排队,直到黄线内满员,然后再等待下一个或是几个办完事情的客户离开再进黄线排队。所以这里涉及到先进先出的问题,我选择了用队列维护,用数组加个标记指针也可以。

每次枚举时间,首先我们把要离开的客户送走,然后用剩下的客户去填满黄线内的位置。怎么判断客户要离开呢?这里我维护了一个每个窗口上一个走掉的客户的时间的数组sum[],每次只要判断基于上一个客户的时间加上这个客户所需要花费的时间是否等于当前的时间即可。需要注意的是,只要在17:00之前处理的客户(即使解决完时间超过17:00),都是输出对应时间

【代码】

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
queue <int> q[25];
int sum[25]={0};
int a[1005],ans[1005];
int main()
{
    int n,m,k,qq; scanf("%d%d%d%d",&n,&m,&k,&qq);
    for(int i=1;i<=n;i++)
        while(!q[i].empty()) q[i].pop();
    for(int i=1;i<=k;i++) scanf("%d",&a[i]),ans[i]=-1;
    int cnt=1;
    for(int i=0;i<540;i++){ //枚举时间
        for(int j=1;j<=n;j++){
            if(!q[j].empty()){ //不为空,确认第一个是否可弹出
                int num=q[j].front();
                if(sum[j]+a[num]==i) ans[num]=sum[j]=i,q[j].pop();
            }
        }
        while(cnt<=k){
            int p=-1,mi=m;
            for(int j=1;j<=n;j++){
                    int l=q[j].size();
                    if(l<mi){
                        mi=l;
                        p=j; //记录最短队伍
                    }
            }
            if(p==-1) break;
            else q[p].push(cnt++);

        }
    }
    for(int i=1;i<=n;i++)
        if(!q[i].empty()) ans[q[i].front()]=sum[i]+a[q[i].front()];
    while(qq--){
        int x; scanf("%d",&x);
        if(ans[x]==-1) printf("Sorry\n");
        else printf("%02d:%02d\n",8+ans[x]/60,ans[x]%60);
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值