一道queue的时间模拟题。最后一个样例没过,不想再改了~
思路是,写一个处理函数,每次处理一个顾客,让他的处理时间归零,然后递加当前时间now,把now存入finish数组中。
有几个坑,首先第一遍题目我读错了,只有开始服务时间在17点之后的顾客才会被sorry,而结束时间在17点之后的正常输出。
第二个坑是会出现几个顾客同时处理完毕的情况,大概有2个测试用例。
在写程序的过程中也要注意很多细节,我一开始犯的一个小错误就是,没有把每个顾客的处理时间单独用一个数组存起来,导致最后算开始时间时_time全变为0了。
#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
int N,M,K,Q;
int _time[1010];
int timecpy[1010];
int finish[1010];
int now = 480; //现在时间
int tempnum = 1; //在黄线外的顾客编号
int finishnumber = 0; //完成的顾客数
queue<int> window[25];
void Paidui()
{
int x = M;
while(x >0)
{
for(int k = 1;k<=N;k++)
{
window[k].push(tempnum++);
}
x--;
}
}
void Process()
{
int firstprocesstime = 100000000; //最先完成的顾客所需时间
int finishwindow; //最先完成的窗口
for(int l = 1;l<=N;l++)
{
int process = _time[window[l].front()];
//printf("%d\n",window[1].front());
if(process<firstprocesstime && process >0)
{
firstprocesstime = process;
finishwindow = l;
}
}
now += firstprocesstime;
//printf("%d\n",now);
for(int w = 1;w<=N;w++)
{
_time[window[w].front()] -= firstprocesstime; //同步柜台处的处理时间
if(w != finishwindow && _time[window[w].front()] == 0) //如果有同时结束的,也要处理
{
finish[window[w].front()] = now;
window[w].pop();
finishnumber++;
}
}
finish[window[finishwindow].front()] = now;
window[finishwindow].pop();
finishnumber++;
if(tempnum<=K) //将等候区的人插队
{
int tempsize = M;
int minwindow;
for(int u = 1; u<=N; u++)
{
if(window[u].size()<tempsize)
{
tempsize = window[u].size();
minwindow = u;
}
}
window[minwindow].push(tempnum++);
}
}
int main()
{
scanf("%d %d %d %d",&N,&M,&K,&Q);
for(int i = 1;i<=K;i++)
{
scanf("%d",&_time[i]);
timecpy[i] = _time[i];
}
Paidui();
while(finishnumber<K) //一次处理一个顾客(可能同时处理两个)
{
Process();
}
for(int j = 1;j<=Q;j++)
{
int temp;
scanf("%d",&temp);
//printf("%d\n",finish[temp]);
if((finish[temp] - timecpy[temp]) < 1020)
{
printf("%02d:%02d\n",finish[temp]/60,finish[temp]%60);
}else
{
printf("Sorry\n");
}
}
return 0;
}