PAT 1014 Waiting in Line (30 分)燚

版权声明:哈哈 你能采纳 我很开心 https://blog.csdn.net/m0_38090681/article/details/84146442

Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:

  • The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (NM+1)st one will have to wait in a line behind the yellow line.
  • Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
  • Customer​i​​ will take T​i​​ minutes to have his/her transaction processed.
  • The first N customers are assumed to be served at 8:00am.

Now given the processing time of each customer, you are supposed to tell the exact time at which a customer has his/her business done.

For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer​1​​ is served at window​1​​ while customer​2​​ is served at window​2​​. Customer​3​​ will wait in front of window​1​​ and customer​4​​ will wait in front of window​2​​. Customer​5​​ will wait behind the yellow line.

At 08:01, customer​1​​ is done and customer​5​​ enters the line in front of window​1​​ since that line seems shorter now. Customer​2​​ will leave at 08:02, customer​4​​ at 08:06, customer​3​​ at 08:07, and finally customer​5​​at 08:10.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (≤20, number of windows), M (≤10, the maximum capacity of each line inside the yellow line), K (≤1000, number of customers), and Q (≤1000, number of customer queries).

The next line contains K positive integers, which are the processing time of the K customers.

The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.

Output Specification:

For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output Sorry instead.

Sample Input:

2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7

Sample Output:

08:07
08:06
08:10
17:00
Sorry

题目大意: 银行有m个窗口,每个窗口前可最多可排列一列n个人的队伍,来银行办理业务的人数为k个,因此剩余的(k-m*n)个人在黄线外的等待区。

输出:在8点到17点以前接受服务的元素都输出其结束时间,其他的输出Sorry

相似题 PAT 1017题  解析传送门:https://mp.csdn.net/postedit/84143215

       排队规则1.每个窗口最前面的办理完业务离开,等待队列队头元素选择一个最短窗口,如果同时有多个相同的最短窗口则选择号数最小的那一个窗口进行排队。

                        2.银行8点开始营业,17点结束营业,凡在此时间区间内开始接受服务的都有效,不管结束时间是否超过17点。

解题思想:1.每个元素只要排进了窗口队列,无论是否接受服务,其服务开始时间和服务结束时间就已固定,因此只需将等待区队列的元素按照上面的排队规则定位到他所在的窗口即可求出每个元素的服务时间。(除头元素外,其他元素的开始时间为上一个元素的结束时间,所以只需记录每个元素的结束时间)

                 2.在银行没开是营业之前将每个窗口的最大等待人数填满(在人数足够的情况下)。

                 3.然后银行开始营业,选出最先结束服务的窗口,扔掉窗口头的元素,用等待队列中的元素去填充,并更新新填充进去的元素的结束时间。从而保证每个窗口人数为n。直到等待队列中的元素被取完为止。然后输出给定元素的结束时间。

坑点:银行8点开始营业,17点结束营业,凡在此时间区间内开始接受服务的都有效,不管结束时间是否超过17点(坑了我两天时间)


#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct Person{
	int needTime;//服务所需时间
	int finishTime;//结束时间
};
void input(int k,int q,vector<Person> &people,vector<int> &resultPerson){
	for(int i=0;i<k;i++){
		cin>>people[i].needTime;
	}
	for(int i=0;i<q;i++){
		cin>>resultPerson[i];
	}
}
//在银行开业前填充每一个窗口
int fillTheQueue(vector<Person>&people,vector<queue<Person>>&que,int m){ 
	int ptr=0; //ptr指向等待区下一个进入窗口队列的元素
	while(que[0].size()<m&&ptr<people.size()){    //判断窗口是否达到最大容量m,否则向窗口填充元素
		for(int i=0;i<que.size()&&ptr<people.size();i++){//向每个窗口添加一个元素
			if(que[i].empty()){
				people[ptr].finishTime=people[ptr].needTime;//如果该窗口为空,则结束时间为办理业务所需时间
			}
			else{
				people[ptr].finishTime=people[ptr].needTime+que[i].back().finishTime;//窗口不为空,结束时间为前一个的结束时间加上自己办理业务所需时间
			}
			que[i].push(people[ptr++]);
		}
	}
	return ptr;
}
//计算每一个人的结束时间
void enQue(vector<Person> &people,int &ptr,vector<queue<Person>>&que){
	while(ptr<people.size()){
	int min=0;
	for(int i=1;i<que.size();i++){  //找出最先办理完业务的窗口
		if(que[i].front().finishTime<que[min].front().finishTime){
			min=i;
		}
	}
	people[ptr].finishTime=people[ptr].needTime+que[min].back().finishTime;//更新新加入的元素的结束时间
	que[min].pop();//将该窗口头元素扔掉
	que[min].push(people[ptr++]);//加入新元素
}
}
//输出
void output(vector<int> &resultPerson,vector<Person>&people){
	for(int i=0;i<resultPerson.size();i++){

		//注意   凡是开始服务时间在17点前都输出,而不是服务结束时间在17点前。开始时间=结束时间-服务时间
		if(people[resultPerson[i]-1].finishTime-people[resultPerson[i]-1].needTime<540)
			printf("%02d:%02d\n",8+people[resultPerson[i]-1].finishTime/60,people[resultPerson[i]-1].finishTime%60);
		else{
			cout<<"Sorry"<<endl;
		}
	}
}
int main(){
	int n,m,k,q;
	cin>>n>>m>>k>>q;
	vector<Person>people(k);  //等待队列
	vector<queue<Person>>que(n); //银行办理窗口队列
	vector<int>resultPerson(q);  //要求输出的元素数组
    input(k,q,people,resultPerson);
	int ptr=fillTheQueue(people,que,m);//ptr指向等待区下一个进入窗口队列的元素
	enQue(people,ptr,que);
	output(resultPerson,people);
}

猜你喜欢

转载自blog.csdn.net/m0_38090681/article/details/84146442