【id:50】【20分】D. DS队列----银行单队列多窗口模拟

题目描述

假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。

本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间。

输入

输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T和事务处理时间P,并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10),为开设的营业窗口数。

输出

在一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。

输入样例1

9
0 20
1 15
1 61
2 10
10 5
10 3
30 18
31 25
31 2
3
输出样例1

6.2 17 62

以下是思路

        这题一开始想了挺久的--该如何判断这个窗口的顾客什么时候该入队,什么时候该出队。一开始想用一个总时间total不断++来进行判断,但这样不仅思考起来麻烦而且敲起来也很折磨。后面用纸写了下就有了个新的思路。

        先看有多少个窗口,向每个窗口都推入一个T=0,P=0的初始结构People,这样方便比较也不用担心窗口为空的情况。(为什么不用担心后面会提到)

        每个People都有一个当前时间curwt(默认值=0),每当你向窗口中push进一个People时,就更新你push进去的这个People的curwt,这个curwt应当等于该窗口上一个People的curwt,这样不断更新curwt一直到list为空时退出循环,此时每个窗口都一定会有一个People(就算这个窗口没有被push过也有一个默认的People,而且因为值都为0所以也不会对结果有影响)

        你push进去的顾客应该是所有窗口里头curwt最小的那个(各位如果这里看不懂可以用纸写一遍这个程序的运行过程),那就在while循环的开头定义一个mint=999;去遍历每个窗口的第一个元素的curwt,如果小于curwt就更新这个mint的值。最后再遍历一次窗口查找匹配值(因为顾客总是选择编号最小的窗口,所以直接if判断就好)。

        至于curwt的更新条件,如果push进行的T(到达时间)大于这个cruwt,那么cruwt就等于T(说明一直到时间T这个顾客才来并开始办理业务)。如果小于的话就看上一个顾客什么时候完成,上一个顾客完成的时间就是你push进去的这个顾客开始办理业务的时间。同时pop出办理完业务的顾客到另一个队列中,这个队列的顺序就是每个顾客完成业务时间的顺序。

        当list为空时,窗口的队列中都会剩下一个顾客,其中有正在办理业务的顾客,也可能有从来没人去过默认值为全0的窗口。那么就先统计出队的队列计算时间,再加上窗口队列的时间即可。最后得到实验输出的样例。

        别忘了最后平均值是保留一位小数,记得用cout << fixed << setprecision(1)输出

        

以下是代码

又看了一遍,感觉最后输出那里判断有点重复了,有兴趣的可以改改看看。

#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;
struct People
{
	int T = 0, P = 0;
	int curwt = 0;
	int waitstate = 0;
	int wait = 0;
};
int main()
{
	queue<People>list;
	int n;
	cin >> n;
	for (int i = 0;i < n;i++)
	{
		People temp;
		cin >> temp.T >> temp.P;
		list.push(temp);
	}
	int w;
	cin >> w;
	queue<People>* windows=new queue<People>[w];
	for (int i = 0;i < w;i++)
	{
		People p;
		windows[i].push(p);
	}
	queue<People>last;
	while (!list.empty())
	{
		int curw = 0;
		int mint = 999;
		while (curw < w)
		{
			if (!windows[curw].empty())
			{
				if (mint > windows[curw].front().curwt)
				{
					mint = windows[curw].front().curwt;
				}
			}
			curw++;
		}
		curw = 0;
		while (curw < w)
		{
			if (!windows[curw].empty())
			{
				if (mint == windows[curw].front().curwt)
				{
					int curtime = windows[curw].front().curwt;
					windows[curw].push(list.front());
					last.push(windows[curw].front());
					windows[curw].pop();
					list.pop();
					if (windows[curw].front().T < curtime)
					{
						windows[curw].front().wait = curtime - windows[curw].front().T;
						windows[curw].front().waitstate = 1;
						windows[curw].front().curwt = curtime+windows[curw].front().P;
					}
					else if (windows[curw].front().T >= curtime)
					{
						curtime = windows[curw].front().T;
						windows[curw].front().curwt = curtime+windows[curw].front().P;
					}
					break;
				}
			}
			curw++;
		}
		
	}
	int curw = 0;int maxt = 0;
	while (curw < w)
	{
		if (!windows[curw].empty())
		{
			if (maxt < windows[curw].front().curwt)
			{
				maxt = windows[curw].front().curwt;
			}
		}
		curw++;
	}
	int maxwait = 0;
	double avet = 0;
	queue<People>temp= last;
	while (!temp.empty())
	{
		if (temp.front().waitstate == 1)
		{
			avet = avet + temp.front().wait;
			if (maxwait < temp.front().wait)
			{
				maxwait = temp.front().wait;
			}
		}
		temp.pop();
	}
	curw = 0;
	while (curw < w)
	{
		if (!windows[curw].empty())
		{
			if (windows[curw].front().waitstate == 1)
			{
				avet = avet + windows[curw].front().wait;
				if (maxwait < windows[curw].front().wait)
				{
					maxwait = windows[curw].front().wait;
				}
			}
		}
		curw++;
	}

	cout << fixed << setprecision(1) << avet/n << " ";
	cout << maxwait << " " << maxt << endl;
	cout << endl;
}

入n个顾客的到达时间,以及每个顾客需要处理的时间,计算所有顾客处理完毕的时间。 算法思路: 1. 创建一个长度为k的数组,表示每个窗口的空闲时间,初始值为。 2. 创建一个队列,表示当前排队的顾客。 3. 遍历每个顾客,将其加入队列中。 4. 当队列不为空时,取出队首顾客,找到空闲时间最早的窗口,将其配给该顾客,更新该窗口的空闲时间。 5. 如果队列中还有顾客,重复步骤4,直到队列为空。 6. 返回最后一个顾客处理完毕的时间。 Python代码实现: def bank_service(k, n, arrive_time, process_time): # 创建一个长度为k的数组,表示每个窗口的空闲时间,初始值为 windows = [] * k # 创建一个队列,表示当前排队的顾客 queue = [] # 遍历每个顾客,将其加入队列中 for i in range(n): queue.append((arrive_time[i], process_time[i])) # 当队列不为空时,取出队首顾客,找到空闲时间最早的窗口,将其配给该顾客,更新该窗口的空闲时间 cur_time = while queue: # 找到空闲时间最早的窗口 idx = windows.index(min(windows)) # 取出队首顾客 arrive, process = queue.pop() # 计算顾客开始处理事务的时间 start_time = max(arrive, windows[idx]) # 更新该窗口的空闲时间 windows[idx] = start_time + process # 更新当前时间 cur_time = max(cur_time, windows[idx]) # 返回最后一个顾客处理完毕的时间 return cur_time # 测试 k = 3 n = 5 arrive_time = [1, 2, 6, 8, 9] process_time = [3, 6, 4, 5, 2] print(bank_service(k, n, arrive_time, process_time)) # 输出:15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值