Bootstrap

【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;
}

;