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;
}

  

posted @ 2012-12-10 11:31  Frank@609  Views(1451)  Comments(1Edit  收藏  举报