PAT Advanced 1014 【Waiting in Line】 (30)

分析:队列的常规操作,理清思路非常关键。

#include<cstdio>
#include<queue>
using namespace std;
const int maxn = 1e3+10;
queue<int> win[30]; 
int serv[maxn], res[maxn], wintime[30];//serv[i]:第i个人的服务时间 wintime[i]:第i个窗口当前的时间 
void pop(int i){
	int top = win[i].front(); //top为第i个窗口最前面的那个人的id 
	win[i].pop();
	res[top] = wintime[i] + serv[top]; //top的离开时间为第i个窗口的时间加上服务时间 
	wintime[i] = res[top]; //更新第i个窗口现在的时间 
}
int main(){
	//freopen("aa.txt", "r", stdin);
	int n, m, k, q, num, cnt = 1, endtime = 17*60;
	scanf("%d %d %d %d", &n, &m, &k, &q);
	for(int i = 1; i<=k; i++)
		scanf("%d", &serv[i]);
	for(int i = 0; i<n; i++)
		wintime[i] = 8*60;	//初始化每个窗口当前的时间为8点 
	for(int i = 0; cnt<=k && cnt<=m*n; i++)
		win[i%n].push(cnt++);	//初始化队列 排成m*n 
	while(cnt <= k){
		int u = 0, minn = wintime[0] + serv[win[0].front()];
		for(int i = 1; i<n; i++){
			int tem = wintime[i] + serv[win[i].front()];
			if(tem < minn){
				minn = tem;  
				u = i; //找出当前服务完第一个人时间最小的窗口 
			}
		}
		if(wintime[u] >= endtime) break; //大于17点即不用入队了 
		pop(u); //把第u个窗口队首出队 
		win[u].push(cnt++); //然后入队 
	}
	for(int i = 0; i<n; i++) //对每一个窗口进行出队操作,直到队空或者大于结束时间 
		while(!win[i].empty() && wintime[i]<endtime)
			pop(i);	
	for(int i = 0; i<q; i++){
		scanf("%d", &num);
		if(res[num] == 0) printf("Sorry\n");
		else printf("%02d:%02d\n", res[num]/60, res[num]%60);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/gq__97/article/details/81560832