题目描述
假设银行有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;
}