PAT 甲级 1017. Queueing at Bank (25)

题目:点击打开链接

思路:1.在输入时,可将达到时间晚于17:00:00的客户排除,不计入名单;

            2.先根据到达时间排序,将情况分为前K位和后K位(K为窗口数)达到两个部分:

               1)对前K位达到,若在8:00:00前达到,则等待时间则为其到8:00:00的时间,这里的服务时间是8:00:00,若在8:00:00后到达则无等待时间,这里的服务时间是其达到时间;

               2)对K位后,先将其之间的K为客户按照其离开时间排序(由于每次都对相应客户的前K位客户进行离开时间排序,最后整个向量排序都将根据离开时间排序,不必担心前面客户先到后出的情况发生),对排序后向前数第K位客户的离开时间作为标准,在此之前达到则有等待时间,否则等待时间为0;

          3.注意客户数小于窗口数的情况。

代码:

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;

int final_time=17*60*60;
int begin_time=8*60*60;


struct customer
{
	int arr_time;
	int p;
	int ser_time;
	int leave_time;	
};
//根据达到时间排序
bool comp_arr(customer &a,customer &b)
{
	return a.arr_time<b.arr_time;
}


//根据离开时间排序
bool comp_leave(customer &a,customer &b)
{
	return a.leave_time<b.leave_time;
}


//计算秒数
int get_time(string s)
{
	int t=0;
	t=(s[6]-'0')*10+(s[7]-'0');
	t+=((s[3]-'0')*10+(s[4]-'0'))*60;
	t+=((s[0]-'0')*10+(s[1]-'0'))*60*60;
	return t;
}


int main()
{
	int N,K;
	cin>>N>>K;
	int i=0;
	vector<customer> C;
	string s;
	int t,q;
	customer cum;

	for(;i<N;++i)
	{
		cin>>s>>q;
		t=get_time(s);
		if(t<=final_time)     //在17:00:01之前到达的客户
		{
		   cum.arr_time=t;
		   cum.p=q;
		   C.push_back(cum);
		}
	}
	sort(C.begin(),C.end(),comp_arr);      //根据到达时间排序
	
	long long w_time=0;    //总的等待时间

	if(C.size()<=K)       //人数小于等于窗口数
	{
		for(i=0;i<C.size();++i)
		{			
			if(C[i].arr_time<begin_time)           //在开始时间之前来,有等待时间
			{
				w_time+=begin_time-C[i].arr_time;
				C[i].ser_time=begin_time;		
			}
			else
			{
				C[i].ser_time=C[i].arr_time;
			}
			C[i].leave_time=C[i].ser_time+C[i].p*60;
		}
	}
	else
	{
		for(i=0;i<K;++i)   //前K位客户,到8:00即可服务
		{
			if(C[i].arr_time<begin_time)           //在开始时间之前来,有等待时间
			{
				w_time+=begin_time-C[i].arr_time;
				C[i].ser_time=begin_time;		
			}
			else
			{
				C[i].ser_time=C[i].arr_time;
			}
			C[i].leave_time=C[i].ser_time+C[i].p*60;
		}
		for(;i<C.size();++i)
		{
			sort(C.begin()+i-K,C.begin()+i,comp_leave);  //对于前K位用户排序
			if(C[i].arr_time<C[i-K].leave_time)          //客户早到
			{
				w_time+=C[i-K].leave_time-C[i].arr_time;
				C[i].ser_time=C[i-K].leave_time;
			}
			else
			{
				C[i].ser_time=C[i].arr_time;
			}
			C[i].leave_time=C[i].ser_time+C[i].p*60;     //离开时间计算
		}
		
	}
	float per_time=w_time/(60.0*C.size());
		printf("%.1f",per_time);
	system("pause");
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值