PAT A1017 Queueing at Bank

23 篇文章 0 订阅
15 篇文章 0 订阅

题目描述

在这里插入图片描述

知识点

STL之priority_queue

实现

码前思考

  1. 时间最好用秒数s来记录
  2. 需要记录到来时间,开始服务时间和结束服务时间;
  3. 记得考虑一个用户运气好,来的时候不用等;
  4. 记得按来的时间排序;

代码实现

//每个window一个人,单人占用部分超过60min
//没有同时到达的客户,就是说大家是有先后次序的!队列
//超过17:00之后来,不当做人看,之前都当作人看,直接忽略
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 1e4+10;
int n;
int k;
int totWait;
int cnt = 0;

struct p{
	//以秒进行计数 
	int ctime;
	int stime;
	int etime;
	int last; 
	friend bool operator < (p a,p b){
		//先结束的,先出来 
		return a.etime > b.etime;
	} 
}ps[maxn];

priority_queue<p> q;

bool cmp(p a,p b){
	return a.ctime < b.ctime;
}

int main(){
	int openTime = 8*60*60;
	int closeTime = 17*60*60;
	
	scanf("%d %d",&n,&k);
	
	for(int i=0;i<n;i++){
		int hh;
		int mm;
		int ss;
		int last;
		scanf("%d:%d:%d %d",&hh,&mm,&ss,&last);
		last = last * 60;
		int ctime = hh * 60 * 60+ mm * 60 + ss;
		p tmp;
		if(ctime <= closeTime){//要等于 
			tmp.ctime = ctime;
			tmp.last = last;
			ps[cnt++] = tmp;		
		}else{
			continue;
		} 
	}
	
	sort(ps,ps+cnt,cmp);
	
//	for(int i=0;i<cnt;i++){
//		printf("%d %d\n",ps[i].ctime,ps[i].last);
//	}
	
	//针对cnt进行计算
	int idx = 0;
	for(;idx<cnt && idx<k;idx++){
		//如果是在开门之前来的,则有等待
		if(ps[idx].ctime < openTime){
			totWait += openTime - ps[idx].ctime;
			ps[idx].stime = openTime;
		}else{
			//不用等 
			ps[idx].stime = ps[idx].ctime;
		}
		ps[idx].etime = ps[idx].stime+ps[idx].last;
		q.push(ps[idx]);
	} 
	
	while(idx<cnt){
		//接下来就是求解了
		p tmp = q.top();
		q.pop();
		//需要进行一个比较,如果这个可以服务时间和你到的时间有问题
		int canTime = tmp.etime;
		if(ps[idx].ctime < canTime){
			totWait += canTime - ps[idx].ctime;
			ps[idx].stime = canTime;		 
		}else{
			ps[idx].stime = ps[idx].ctime;
		} 	
		ps[idx].etime = ps[idx].stime+ps[idx].last;
		q.push(ps[idx]);
		idx++; 
	}
	
	printf("%.1f",totWait*1.0/60/cnt); 
	return 0;
} 

码后反思

  1. 主要是考察优先队列的使用。

二刷代码

  1. 二刷的代码没有一刷那么清晰明了。。。我退步了;
  2. 一刷的时候我有提醒自己要注意不用等的情况,但是二刷的时候两个循环都忘记考虑不要等的时候,结束时间就是到达时间加运行时间;
  3. 我的代码里面有很多硬编码。。。比如银行的营业范围。
  4. 对于17点以后的,在一开始就不放入vector为好;
  5. 结构体用的也不太好,省略了太多关键信息了,不太好。。。
  6. 结构体构造函数反而使代码变复杂了,不行啊
//纯粹考察STL的使用 
//时间用秒来表示 
//入队列时就统计等待时间
 
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

struct node{
	int atime;
	int ptime;
	int etime; 
	node(){}
	node(int a,int p):atime(a),ptime(p),etime(-1){}
	node(int a,int p,int e):atime(a),ptime(p),etime(e){}
	
	friend bool operator < (node a,node b){
		return a.etime > b.etime;//注意这里是大于号,和cmp是不同的 
	} 
};

int n;
int k;
double totwait=0.0; 
vector<node> lst;
priority_queue<node> q; 

bool cmp(node a,node b){
	return a.atime < b.atime;
}

int main(){
	//freopen("input.txt","r",stdin);
	scanf("%d %d",&n,&k);
	for(int i=0;i<n;i++){
		int hh,mm,ss,p;
		scanf("%d:%d:%d %d",&hh,&mm,&ss,&p);
		lst.push_back(node(hh*60*60+mm*60+ss,p*60));
	}
	sort(lst.begin(),lst.end(),cmp);//按照到达时间排序
	
	//接下来首先进队列一些人
	int idx; 
	for(idx=0;idx<k&&idx<lst.size()&&lst[idx].atime < 17*60*60+1;idx++){//注意这个范围啊,要小于lst 
		if(lst[idx].atime < 8*60*60){
			totwait += 8*60*60-lst[idx].atime;//需要等待的 
			q.push(node(lst[idx].atime,lst[idx].ptime,8*60*60+lst[idx].ptime));
		}else{
			//然后入队
			q.push(node(lst[idx].atime,lst[idx].ptime,lst[idx].atime+lst[idx].ptime)); 			
		}
	}
	
	//接下来就是不停的出队列,入队列
	while(!q.empty() && idx < lst.size() && lst[idx].atime < 17*60*60+1){
		node out = q.top();	//队列是不可能提前为空的?
		node cur = lst[idx];
		
		//计算等待时间
		if(cur.atime < out.etime){
			totwait += out.etime - cur.atime; 
			q.push(node(cur.atime,cur.ptime,out.etime+cur.ptime));//注意结束时间 
		}else{
			q.push(node(cur.atime,cur.ptime,cur.atime+cur.ptime));//注意结束时间 			
		}

		q.pop();//记得弹出
		idx++; 
	} 
	
	printf("%.1f",totwait/idx/60);	

	
	 
	return 0;
}

改一下:

//纯粹考察STL的使用 
//时间用秒来表示 
//入队列时就统计等待时间
 
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

struct node{
	int atime;
	int ptime;
	int etime; 
	node(){}
	node(int a,int p):atime(a),ptime(p),etime(-1){}
	node(int a,int p,int e):atime(a),ptime(p),etime(e){}
	
	friend bool operator < (node a,node b){
		return a.etime > b.etime;//注意这里是大于号,和cmp是不同的 
	} 
};

int n;
int k;
double totwait=0.0; 
vector<node> lst;
priority_queue<node> q; 
int opentime = 8*60*60;
int closetime = 17*60*60;

bool cmp(node a,node b){
	return a.atime < b.atime;
}

int main(){
	//freopen("input.txt","r",stdin);
	scanf("%d %d",&n,&k);
	for(int i=0;i<n;i++){
		int hh,mm,ss,p;
		scanf("%d:%d:%d %d",&hh,&mm,&ss,&p);
		if(hh*60*60+mm*60+ss <= closetime){
			lst.push_back(node(hh*60*60+mm*60+ss,p*60));			
		}
	}
	sort(lst.begin(),lst.end(),cmp);//按照到达时间排序
	
	//接下来首先进队列一些人
	int idx; 
	for(idx=0;idx<k&&idx<lst.size();idx++){//注意这个范围啊,要小于lst 
		if(lst[idx].atime < opentime){
			totwait += opentime-lst[idx].atime;//需要等待的 
			q.push(node(lst[idx].atime,lst[idx].ptime,opentime+lst[idx].ptime));
		}else{
			//然后入队
			q.push(node(lst[idx].atime,lst[idx].ptime,lst[idx].atime+lst[idx].ptime)); 			
		}
	}
	
	//接下来就是不停的出队列,入队列
	while(idx < lst.size()){
		node out = q.top();	//队列是不可能提前为空的?
		node cur = lst[idx];
		
		//计算等待时间
		if(cur.atime < out.etime){
			totwait += out.etime - cur.atime; 
			q.push(node(cur.atime,cur.ptime,out.etime+cur.ptime));//注意结束时间 
		}else{
			q.push(node(cur.atime,cur.ptime,cur.atime+cur.ptime));//注意结束时间 			
		}

		q.pop();//记得弹出
		idx++; 
	} 
	
	printf("%.1f",totwait/idx/60);	

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值