【题意】
模拟银行排队
【思路】
直接模拟,设置n个代表窗口的队列以及1个等待队列
【注意点】
1.
17:00之前开始受理的用户即使结束时间超过了17:00,也不能输出Sorry;
2.
可能同时有多个窗口空出来;
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAX 0x0fffffff
void printDigit(int number){
if (number<10)
{
cout << 0;
}
cout << number;
}
void print(int finishTime, int valid){
if(!valid)
cout << "Sorry";
else{
printDigit(finishTime/60+8);
cout << ':';
printDigit(finishTime%60);
}
}
//返回正在处理的顾客中剩余时间最短的编号
int findMin(int *topTime,int n){
int min = MAX;
int index = -1;
for(int i=0; i<n; i++){
if(topTime[i]<min && topTime[i]>0){
min = topTime[i];
index = i;
}
}
return index;
}
int main(int argc, char const *argv[])
{
int n,m,k,q;
int processTime[1000],finishTime[1000],valid[1000];//valid标记计算的结束时间超过540是否返回Sorry,为1则不返回Sorry
int windowTime[20];
queue<int> windows[20],wait;
int topTime[20];
memset(finishTime,0,sizeof(finishTime));
memset(windowTime,0,sizeof(windowTime));
memset(topTime,0,sizeof(topTime));
memset(valid,1,sizeof(valid));
cin >> n >> m >> k >> q;
for (int i = 0; i < k; ++i)
{
cin >> processTime[i];
}
for(int i=0; i<k && i<n*m; i++){
windows[i%n].push(i);
}
if(k>n*m){
for(int i=n*m; i<k; i++){
wait.push(i);
}
}
for(int i=0; i<n && i<k; i++){
int index = windows[i].front();
topTime[i] = processTime[index];
}
int count = k;//未处理完的客户数
int totalTime = 0;
while(count--){
int index = findMin(topTime, n);//即将处理好的队列号
int costTime = topTime[index];
totalTime += costTime;
for(int i=0; i<n; i++){
int number;
if(!windows[i].empty()){
number = windows[i].front();
processTime[number] -= costTime;
if(processTime[number] == 0){
finishTime[number] = totalTime;
windows[i].pop();
if(!wait.empty()){
int waitNum = wait.front();
wait.pop();
windows[i].push(waitNum);
}
if(!windows[i].empty()){
number = windows[i].front();
if(totalTime>=540)
valid[number] = 0;
}
}
topTime[i] = processTime[number];
}
}
}
int queryNumber;
for (int i = 0; i < q; ++i)
{
cin >> queryNumber;
print(finishTime[queryNumber-1], valid[queryNumber-1]);
if (i!=q-1)
{
cout << endl;
}
}
system("pause");
return 0;
}