PAT 甲级 A1017

题目连接

Queueing at Bank (25分)

题目大意

给定N个顾客,K个服务窗口一系列的用户到达时间,需要服务的时间。最后需要输出平均等待时间。注意,只考虑在银行营业期间到来的顾客

思路

  1. 由于给的时间数据(hh:mm:ss)有点麻烦,为了方便计算需要先转化为最小的时间粒度单位,比如秒。时间统一转化函数如下:
    int convertTime(int h, int m, int s) {
    	return h * 3600 + m * 60 + s;
    }
    
  2. 设置一个数组W[105],表示的是窗口结束服务时间,初始为08:00(需要转化为秒)。对到来的每一个顾客,分两种情况,更新窗口的结束服务时间。每个顾客遍历K个窗口,时间复杂度为O(WN)

AC代码

#include<iostream>
#include<algorithm>
#include<vector>
#define INF ((1 << 31) - 1)
using namespace std;
struct customer {
	int comeTime, serveTime;
}newCustomer;
//保存K个窗口的结束使用时间
int w[105];
vector<customer> que;
int convertTime(int h, int m, int s) {
	return h * 3600 + m * 60 + s;
}
bool cmp(customer a, customer b) {
	return a.comeTime < b.comeTime;
}
int main() {
	int c, wNums, totalTime = 0;
	int openTime = convertTime(8, 0, 0);
	int closeTime = convertTime(17, 0, 0);
	scanf("%d%d", &c, &wNums);
	for (int i = 0; i < wNums; i++) w[i] = openTime;
	for (int i = 0; i < c; i++) {
		int h, m, s,serveTime;
		scanf("%d:%d:%d %d", &h, &m, &s, &serveTime);
		int comeTime = convertTime(h, m, s);
		if (comeTime < closeTime) {
			newCustomer.comeTime = comeTime;
			newCustomer.serveTime = serveTime > 60 ? 3600 : serveTime * 60;
			que.push_back(newCustomer);
		}
	}

	sort(que.begin(), que.end(), cmp);
	for (int i = 0; i < que.size(); i++) {
		int idx = -1, minEndTime = INF;

		//最早可用窗口
		for (int j = 0; j < wNums; j++) {
			if (w[j] < minEndTime) {
				minEndTime = w[j];
				idx = j;
			}
		}

		if (que[i].comeTime < w[idx]) {   //需要等,计算此customer等待时间
			totalTime += w[idx] - que[i].comeTime;
			w[idx] += que[i].serveTime;			
		}
		else {
			w[idx] = que[i].comeTime + que[i].serveTime;
		}
	}
	printf("%.1f", totalTime*1.0 / (que.size() * 60));
	return 0;
}
发布了24 篇原创文章 · 获赞 3 · 访问量 1732

猜你喜欢

转载自blog.csdn.net/qq_38507937/article/details/105230738