PAT 1014 Waiting in Line (30)
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<iomanip>
using namespace std;
//本题容易出错的地方:是在17:00及以后开始服务的客户输出"Sorry",而不是17:00之前结束服务的输出"Sorry";
//如客户cId是16:59开始服务,服务时间为2,则输出的应该是17:01,而不是"Sorry"。
const int SIZE = 1005;
int T[1005];
int Query[1005];
int N,M,K,Q;
class Windows
{
public:
int curTime; //当前队首客户开始服务的时间。
int curSerIndex;//等待队列的下标。
int totalTime; //当前窗口队尾客户服务完成时所需要的时间。
vector<int> vWait;
Windows()
{
curTime = 0;
curSerIndex = 0;
totalTime = 0;
}
};
struct Node
{
int cId;//客户编号
int serTime;//服务时间,以分钟为单位,从08:00开始算
};
//窗口信息数组
vector<Windows> vWin;
vector<Node> vCusTimeInfo;//保存每个客户的服务截止时间
int getAFreeWin()
{
//获取队列人数最少的窗口,即最先完成服务的窗口;
int tmpWinId = 0,i;
//当前时间+在窗口等待的第一个人所需要的服务时间。
int tmpIndex = vWin[0].curSerIndex;
int minTime = vWin[0].curTime + T[vWin[0].vWait[tmpIndex]];
for(i=1; i<N; i++)
{
tmpIndex = vWin[i].curSerIndex;
int tmpCurTime = vWin[i].curTime + T[vWin[i].vWait[tmpIndex]];
if(tmpCurTime < minTime)
{
tmpWinId = i;
minTime = tmpCurTime;
}
}
return tmpWinId;
}
//保存窗口为iWinId,客户编号为cId的客户服务所需时间信息。
void storeCusInfo(int iWinId, int cId)
{
Node tmpNode;
tmpNode.cId = cId;
tmpNode.serTime = vWin[iWinId].totalTime;
vCusTimeInfo.push_back(tmpNode);
}
//以正常的格式打印出时间信息
void printTimeInNormal(int iTime, int cId)
{
char strHour[][3] = {"08","09","10","11","12","13","14","15","16","17"};
int min = iTime%60;
int hour = iTime/60;
if( (iTime-T[cId]) >= 540) //是否能在17:00之前服务
cout<<"Sorry"<<endl;
else
{
if(min < 10)
cout<<strHour[hour]<<":0"<<min<<endl;
else
cout<<strHour[hour]<<":"<<min<<endl;
}
}
//找到用户id为iCusId的用户完成服务所需要的时间。
void printCusSerTime(int iCusId)
{
vector<Node>::iterator it = vCusTimeInfo.begin();
while(it != vCusTimeInfo.end())
{
if(it->cId == iCusId)//找到该用户的时间信息
{
printTimeInNormal(it->serTime,it->cId );
}
it++;
}
}
int main()
{
int i,j;
//输入
cin>>N>>M>>K>>Q;
for(i=1; i<=K; i++)
cin>>T[i];
for(i=1; i<=Q; i++)
cin>>Query[i];
//初始化N个窗口
for(i=0; i<N; i++)
{
Windows *tmpWin = new Windows();
vWin.push_back(*tmpWin);
}
//开始入队
int curId = 1;
for(i=0; i<M && curId <= K; i++) //每个窗口最多排M个人
{
for(j=0; j<N && curId <= K; j++)
{
vWin[j].vWait.push_back(curId);
vWin[j].totalTime += T[curId];
storeCusInfo(j,curId);
curId++;
}
}
//处理在等待队列上的客户
while(curId <= K)
{
// cout<<"vWin[0].totalTime: "<<vWin[0].totalTime<<endl;
// cout<<"vWin[1].totalTime: "<<vWin[1].totalTime<<endl;
int iWinId = getAFreeWin();
int tmpCurSerIndex = vWin[iWinId].curSerIndex;
//完成了队首的服务,curSerIndex++
vWin[iWinId].curSerIndex++;
//tmpCid为在窗口iWinId等待的第一个客户
int tmpCId = vWin[iWinId].vWait[tmpCurSerIndex];
vWin[iWinId].curTime += T[tmpCId];
//将当前的客户加入窗口iWinId中。
vWin[iWinId].vWait.push_back(curId);
vWin[iWinId].totalTime += T[curId];
storeCusInfo(iWinId,curId);
curId++;//处理在黄线外的等待队列的下一个客户
}
// cout<<"vWin[0].totalTime: "<<vWin[0].totalTime<<endl;
// for(vector<Node>::iterator it=vCusTimeInfo.begin(); it!=vCusTimeInfo.end(); it++)
// {
// cout<<it->cId<<" "<<it->serTime<<endl;
// }
for(i=1; i<=Q; i++)
printCusSerTime(Query[i]);
return 0;
}
多学习,多总结。

浙公网安备 33010602011771号