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; }
多学习,多总结。