数据结构与算法题目集7-48——银行排队问题之单窗口“夹塞”版

版权声明:我的GitHub:https://github.com/617076674。真诚求星! https://blog.csdn.net/qq_41231926/article/details/84943906

我的数据结构与算法题目集代码仓:https://github.com/617076674/Data-structure-and-algorithm-topic-set

原题链接:https://pintia.cn/problem-sets/15/problems/895

题目描述:

思路:模拟银行排队问题

(1)用一个unordered_map<string, int>类型的变量friendMap记录拥有朋友圈的人名对应的朋友圈编号。

(2)用一个unordered_map<string, int>类型的变量customerId记录每个人名的到达顺序。

(3)用一个bool型的visited[]数组标记第i个到达的人是否被服务过。

(4)用一个vector<string>类型的数组friends[]存储朋友圈编号为i的朋友名。

(5)用一个int型变量window存储窗口能接受下一次服务的最早时间。

注意点:

(1)对于朋友圈中的人,如果其到达时间迟于上一个朋友处理完毕的时间,即窗口时间,则无法插队

(2)如果在friendMap中没有找到某人名,说明这个人不属于任何朋友圈,单独处理这个人就行了

(3)对于每个朋友圈中的人名,都需要按照到达顺序进行排序

(4)如果客户的到达时间大于window,需要将window更新为该客户的到达时间加上该客户的处理时间

时间复杂度和空间复杂度均与输入的朋友圈组成有关。

给出本题各个测试点的测试数据:

序号 输入 输出 说明
0

6 0

JIM 0 20

BOB 0 15

ANN 0 30

AMY 0 2

ZOE 1 61

JOE 3 10

JIM

BOB

ANN

AMY

ZOE

JOE

51.7

没有朋友圈,即无人夹塞。

ZOE的处理时间超过了60分钟,按60分钟计算。

1

6 2

3 ANN BOB JOE

2 JIM ZOE

JIM 0 20

BOB 0 15

ANN 0 30

AMY 0 2

ZOE 1 61

JOE 3 10

JIM

ZOE

BOB

ANN

JOE

AMY

75.2 

ANN、JOE和ZOE夹塞,导致没有朋友的AMY一直排在最后。
2

6 2

3 ANN BOB JOE

2 JIM ZOE

JIM 0 20

BOB 0 15

AMY 0 2

ZOE 21 61

ANN 35 30

JOE 45 10

JIM

BOB

ANN

JOE

AMY

ZOE

28.5

ANN刚好赶上BOB处理完自己的事务,不用等待就夹塞;而ZOE虽然跟JIM是朋友,但是他到达的时候JIM已经走了,于是只好排队。
3

6 2

3 ANN BOB JOE

2 JIM ZOE

JIM 0 20

BOB 22 15

AMY 22 2

ZOE 22 61

ANN 35 30

JOE 45 10

JIM

BOB

ANN

JOE

AMY

ZOE

22.7

窗口有完全空闲的一段时间,等待BOB到来。
4

2 1

2 AAA ZZZ

AAA 1 20

ZZZ 2 10

AAA

ZZZ

9.5

边界测试,只有2位顾客,且名字取到最大、最小值。
5

1 0

ANN 1 20

ANN

0.0

边界测试:只有1位顾客。
6 随机大数据,包含10000名顾客,其中100个朋友圈,每个圈子有100名朋友。 边界测试:上界测试。

C++代码:

#include<iostream>
#include<cstring>
#include<unordered_map>
#include<vector>
#include<algorithm>

using namespace std;

struct customer {	//定义顾客结构体 
	char name[4];
	int arriveTime, processTime;
};

int N, M;
unordered_map<string, int> friendMap, customerId;	//friendMap存储每个人所属的朋友圈编号,customerId存储每个人名的到达顺序 
bool visited[10000];	//visited[]数组标记第i个到达的人是否已经被处理过 
vector<string> friends[100], result;	//friends[i]存储朋友圈编号为i的朋友名,result存储结果 

bool cmp(string s1, string s2);

int main() {
	scanf("%d %d", &N, &M);
	fill(visited, visited + N, false); 
	for(int i = 0; i < M; i++) {
		int L;
		scanf("%d", &L);
		for(int j = 0; j < L; j++) {
			char name[4];
			scanf("%s", name);
			friendMap[name] = i;
			friends[i].push_back(name);
		}
	}
	customer customers[N];
	for(int i = 0; i < N; i++) {
		char name[4];
		scanf("%s %d %d", name, &customers[i].arriveTime, &customers[i].processTime);
		if(customers[i].processTime > 60) {	//如果单次处理时间超过60,当作60处理 
			customers[i].processTime = 60;
		}
		strcpy(customers[i].name, name);
		customerId[name] = i;
	}
	int totalTime = 0;	//总等待时间 
	int window = customers[0].arriveTime;	//一开始的窗口时间应该设置为最先到达的顾客的到达时间 
	for(int i = 0; i < N; i++) {
		if(visited[i]) {	//如果该顾客已经被处理过了,则跳过本次循环 
			continue;
		}
		if(friendMap.find(customers[i].name) == friendMap.end()) {	//如果该顾客不属于任何一个朋友圈 
			if(window > customers[i].arriveTime) {	//如果窗口时间大于顾客的到达时间 
				totalTime += window - customers[i].arriveTime;	//总等待时间增加 
				window += customers[i].processTime;	//窗口时间加上该顾客的处理时间 
			}else{
				window = customers[i].arriveTime + customers[i].processTime;	//窗口时间更新为顾客的到达时间加上该顾客的处理时间 
			}
			visited[i] = true;	
			result.push_back(customers[i].name);
			continue;	//跳过本次循环 
		}
		int friendID = friendMap[customers[i].name];
		sort(friends[friendID].begin(), friends[friendID].end(), cmp);	//对该顾客所属朋友圈的朋友按到达顺序进行排序 
		for(int j = 0; j < friends[friendID].size(); j++) {
			int id = customerId[friends[friendID][j]];
			if(j > 0 && customers[id].arriveTime > window){	//如果下一个朋友的在window的空闲时间之前没有到达,则无法插队 
				break;
			}
			if(visited[id]){
				continue;
			}
			if(window > customers[id].arriveTime) {
				totalTime += window - customers[id].arriveTime;
				window += customers[id].processTime;
			} else {
				window = customers[id].arriveTime + customers[id].processTime;
			}
			visited[id] = true;
			result.push_back(friends[friendID][j]);
		}
	}
	for(int i = 0; i < result.size(); i++) {	//输出结果 
		printf("%s\n", result[i].c_str());
	}
	printf("%.1f\n", totalTime * 1.0 / N);
	return 0;
}

bool cmp(string s1, string s2) {
	return customerId[s1] < customerId[s2];
}

C++解题报告:

猜你喜欢

转载自blog.csdn.net/qq_41231926/article/details/84943906