pat 1014

本文介绍了一种算法,用于解决银行排队问题,通过合理分配客户至黄线前和黄线后的队伍,确保每位客户在规定时间内完成业务。算法采用优先队列策略,有效管理排队顺序和业务处理时间。

题意:大概是说银行的队伍分黄线前和黄先后两种,黄线前有n个柜台,每个柜台可以排m个人,黄先后只站一排,最前面的人总是会站到黄线前人最少且序号尽量小的队伍中去,银行早上8点开门,17点关门,已知每个用户办理业务所需的时间,求每个用户何时能办完业务,如果一个用户的业务在17点之前还没开始就输出sorry

思路:思路还是比较清晰的,我们可以很容易的知道前n*m个人,会横向站到黄线前的队伍中去,所以他们的时间都可以容易的求出来,主要问题是黄线后的人,很明显,他始终站到黄线前第一个走的人的队伍中(同时的话序号最小),所以我们对黄线前的所有用户建一个优先队列,这样每次队首元素所在的队伍序号就是黄先后第一个人回去的队伍,这样只要每次记录每个队伍所有人业务结束的时间,就可以知道下一个人在什么时候结束业务,注意记录sorry的情况

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;


struct PP
{
	int time,id;
};


struct QQ
{
	bool operator() (const PP &a,const PP &b) const{
		if(a.time==b.time) return a.id>b.id;
		return a.time>b.time;
	}
};


priority_queue<PP,vector<PP>,QQ> Q;


int n,m,k,q;
int T[1005],pro[1005],ans[1005];
bool mark[1005];


int main()
{
	int i,j,temp=-1;
	memset(mark,false,sizeof(mark));
	scanf("%d%d%d%d",&n,&m,&k,&q);
	for(i=0;i<k;i++)
		scanf("%d",&T[i]);
	for(i=0;i<n;i++) pro[i]=8*60;
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++) 
		{
			temp++;
			if(temp>=k) break;
			PP New;
			if(pro[j]>=17*60) mark[temp]=1;
			pro[j]+=T[temp];
			ans[temp]=pro[j]; 
			New.time=pro[j];
			New.id=j;
			Q.push(New);
		}
	}
	while(temp++<k)
	{
		PP t=Q.top();
		Q.pop();
		if(pro[t.id]>=17*60) mark[temp]=1;
		pro[t.id]+=T[temp];
		ans[temp]=pro[t.id];
		PP New;
		New.id=t.id;
		New.time=pro[t.id];
		Q.push(New);
	}
	for(i=0;i<q;i++)
	{
		int a;
		scanf("%d",&a);
		a--;
		if(!mark[a])
			printf("%02d:%02d\n",ans[a]/60,ans[a]%60);
		else puts("Sorry");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值