PAT.A1014 Waiting in Line

返回目录在这里插入图片描述在这里插入图片描述

题意

某银行有N个窗口,每个窗口前最多可以排M个人。现在有K位客户需要服务,每位客户的服务时长已知。假设所有客户均在08:00按客户编号次序等在黄线外,且如果有窗口的排队人数没有排满(没有达到M人),当前在黄线外的第一一 个客户就会选择这样的窗口中排队人数最少的窗口去排队(排队人数相同时,选择窗口序号最小的窗口去排队)。给出Q个查询,每个查询给出一位客户的编号,输出这位客户的服务结束时间。注意:如果一个客户在17:00之后(含17:00)还没有被服务,则不再服务,输出Sory;而如果一个客户在 17:00前被服务,那不管服务时间多久,都会服务完。

样例(可复制)

2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
//output
08:07
08:06
08:10
17:00
Sorry

注意点

  1. 如果客户在17.00前进行服务,就算服务结束在17.00后,也要输出。
  2. 把时间转换成分钟作为基本单位处理起来更方便。
#include<bits/stdc++.h>
using namespace std;

const int maxnode=1111;
int n,m,k,q,query;
int ans[maxnode],need[maxnode];//ans存放服务结束时间,need存储服务需要时间 
struct window{
	int endtime,poptime;//当前窗口最后服务时间,队首客户的服务结束时间
	queue<int> q;
}win[20];
int gettime(int h,int m) {
	return h*60+m;
}
int main(){
	cin>>n>>m>>k>>query;//窗口数,窗口人口上限,客户数,查询数 
	for(int i=0;i<k;i++)scanf("%d",&need[i]);
	for(int i=0;i<n;i++){//初始化所有窗口 
		win[i].endtime=win[i].poptime=gettime(8,0);
	}
	int now=0;//客户入队编号 
	for(int i=0;i<min(n*m,k);i++){
		win[now%n].q.push(now);
		win[now%n].endtime+=need[now];
		if(now<n)win[now].poptime=need[now];
		ans[now]=win[now%n].endtime;
		now++;
	}
	for(;now<k;now++){
		int idx,minn=INT_MAX;
		for(int i=0;i<n;i++){
			if(win[i].poptime<minn){
				idx=i;
				minn=win[i].poptime;
			}
		}
		window& w=win[idx];
		w.q.pop();
		w.q.push(now);//now进入黄线内窗口idx处进行排队
		w.endtime+=need[now];
		w.poptime+=need[w.q.front()];
		ans[now]=w.endtime;
	}
	for(int i=0;i<query;i++){
		scanf("%d",&q);
		if(ans[q-1]-need[q-1]>=gettime(17,0))printf("Sorry\n");
		else printf("%02d:%02d\n",ans[q-1]/60,ans[q-1]%60);
	}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小怪兽会微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值