PAT 1026 Table Tennis
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<iomanip>
#include<algorithm>
using namespace std;
const int MAX_N = 10000+5;
const int MAX_TABLE = 100+5;
const int OFF_TIME = 13*60*60;
const int TWO_HOUR = 2*60*60; //每组最多只能占用桌子2个小时的时间。
struct Player
{
int iArrTime; //到达的时间
int iPlayTime; //运动的时间
int iWaitTime; //等待的时间
bool isServed;//是否在21:00之前得到桌子
bool isVip; //是否为VIP会员
};
Player arrPlayers[MAX_N];
struct Tables
{
int iAvaiTime;//桌子available的时间
int iCount;//服务了多少组
bool isVip; //是否为VIP桌子
};
Tables arrTables[MAX_TABLE];
int N,K,M; //N个players,K张桌子,M张VIP桌子
//按到达时间进行排序
bool lessCmp(Player p1, Player p2)
{
return p1.iArrTime < p2.iArrTime;
}
//按服务时间先后进行排序
bool lessCmp2(Player p1, Player p2)
{
return (p1.iWaitTime+p1.iArrTime) < (p2.iWaitTime+p2.iArrTime);
}
//将07:55:00形式的时间转换为相对08:00的时间,单位:秒。
//如果早于8点,则返回负数。
int getRelTime(char *chTime)
{
int iRes;
int h = (chTime[0] - '0')*10 + chTime[1]-'0';
int m = (chTime[3] - '0')*10 + chTime[4]-'0';
int s = (chTime[6] - '0')*10 + chTime[7]-'0';
int iEight = 8*60*60;
int iNow = (h*60 + m)*60 + s;
iRes = iNow - iEight;
return iRes;
}
//数据输入和初始化
void inputData()
{
int i,j,iTabId,iPlayTimeMins;
cin>>N;
char chArriveTime[15];
for(i=1; i<=N; i++)
{
cin>>chArriveTime;
arrPlayers[i].iArrTime = getRelTime(chArriveTime);
cin>>iPlayTimeMins;
//将分钟转换为妙
arrPlayers[i].iPlayTime = iPlayTimeMins*60;
cin>>arrPlayers[i].isVip;
arrPlayers[i].iWaitTime = 0;
arrPlayers[i].isServed = false;
}
cin>>K>>M;
for(i=1; i<=K; i++)
{
arrTables[i].iAvaiTime = 0;
arrTables[i].iCount = 0;
arrTables[i].isVip = false;
}
for(j=1; j<=M; j++)
{
cin>>iTabId;
arrTables[iTabId].isVip = true;
}
}
//得到一个空闲的桌子,遍历K个桌子,找到桌子的available时间小于iCurTime且编号最小的桌子。
//如果所有的桌子的avaliable时间都大于iCurTime,则找到avaliable最早的时间;
//注意编号为1到K。
int getAnFreeTab(int K, int iCurTime)
{
int i=0;
for(i=1; i<=K; i++)
if(arrTables[i].iAvaiTime < iCurTime)
return i;
int iAvaTimeMin = arrTables[1].iAvaiTime;
int iTabId = 1;
for(i=2; i<=K; i++)
if(arrTables[i].iAvaiTime < iAvaTimeMin)
{
iAvaTimeMin = arrTables[i].iAvaiTime;
iTabId = i;
}
return iTabId;
}
int max(int a,int b)
{
return a>b?a:b;
}
//窗口iWinId处理完一个客户后,需要更新窗口available最早的时间
void updateWinsInfo(int iTableId,int iPlayerId)
{
int iCurTime = max(arrTables[iTableId].iAvaiTime,arrPlayers[iPlayerId].iArrTime);
if(arrPlayers[iPlayerId].iPlayTime <= TWO_HOUR)//处理的时间不能超过一个小时
arrTables[iTableId].iAvaiTime =iCurTime + arrPlayers[iPlayerId].iPlayTime;
else
arrTables[iTableId].iAvaiTime =iCurTime + TWO_HOUR;
}
//将iPlayerId客户放到桌子iTableId进行处理
void processAnCus(int iTableId, int iPlayerId)
{
//开始就空闲的桌子
if(arrTables[iTableId].iAvaiTime == 0)
{
arrPlayers[iPlayerId].iWaitTime = 0;
arrPlayers[iPlayerId].isServed = true;
arrTables[iTableId].iCount++;
}
else//处理过客户的桌子
{
if(arrTables[iTableId].iAvaiTime >= OFF_TIME) //未在关门前得到桌子
{
arrPlayers[iPlayerId].iWaitTime = 0;
arrPlayers[iPlayerId].isServed = false;
}
else
{
if(arrTables[iTableId].iAvaiTime <= arrPlayers[iPlayerId].iArrTime)
arrPlayers[iPlayerId].iWaitTime = 0;
else
arrPlayers[iPlayerId].iWaitTime = arrTables[iTableId].iAvaiTime - arrPlayers[iPlayerId].iArrTime;
arrPlayers[iPlayerId].isServed = true;
arrTables[iTableId].iCount++;
}
}
updateWinsInfo(iTableId,iPlayerId);
}
//获得在当前时间的等待队列的一个VIP用户的下标,从iPlayerId开始查找;如果等待队列中没有VIP用户,则返回-1;
int getAnVipPlayer(int iPlayerId, int iCurTime)
{
for(int i=iPlayerId; i<=N; i++)
if(arrPlayers[i].isVip && arrPlayers[i].iArrTime<iCurTime)
return i;
return -1;
}
//对在等待队列上的客户进行处理
void process()
{
//下标从1开始,所以sort时要注意。
sort(arrPlayers+1,arrPlayers+N+1,lessCmp);
int iPlayerId = 1;
while(iPlayerId <= N)
{
//如果已经服务过,则pass
if(arrPlayers[iPlayerId].isServed)
{
iPlayerId++;
continue;
}
else
{
int iFreeTabId = getAnFreeTab(K, arrPlayers[iPlayerId].iArrTime);
if(arrTables[iFreeTabId].isVip) //VIP桌子空闲时,应该让等待队列中的VIP用户优先使用
{
//在当前时间的等待队列中找到一个VIP用户。
int tmpId = getAnVipPlayer(iPlayerId, arrTables[iFreeTabId].iAvaiTime);
if(tmpId == -1)//没有VIP用户,则把VIP桌子分配给当前用户
{
processAnCus(iFreeTabId, iPlayerId);
iPlayerId++;
}
else //否则把桌子分配给VIP用户tmpId
{
processAnCus(iFreeTabId, tmpId);
}
}
else //非VIP桌子空闲,则分配给当前用户
{
processAnCus(iFreeTabId, iPlayerId);
iPlayerId++;
}
}
}
}
//以正常的格式打印出时间信息
void printTimeInNormal(int iSec)
{
int tmp = iSec;
char strHour[][3] = {"08","09","10","11","12","13","14","15","16","17","18","19","20","21"};
int sec = tmp%60;
tmp /= 60;
int min = tmp%60;
int hour = tmp/60;
if(min < 10)
{
cout<<strHour[hour]<<":0"<<min;
}
else
cout<<strHour[hour]<<":"<<min;
if(sec < 10)
cout<<":0"<<sec;
else
cout<<":"<<sec;
}
void outputRes()
{
sort(arrPlayers+1,arrPlayers+N+1,lessCmp2);
int i,j,tmp;
for(i=1; i<=N; i++)
if(arrPlayers[i].isServed)
{
printTimeInNormal(arrPlayers[i].iArrTime);
cout<<" ";
printTimeInNormal(arrPlayers[i].iArrTime + arrPlayers[i].iWaitTime);
if(arrPlayers[i].iWaitTime%60 >= 30)
cout<<" "<<arrPlayers[i].iWaitTime/60 + 1<<endl;
else
cout<<" "<<arrPlayers[i].iWaitTime/60<<endl;
}
for(j=1; j<=K; j++)
{
if(j == 1)
cout<<arrTables[j].iCount;
else
cout<<" "<<arrTables[j].iCount;
}
cout<<endl;
}
int main()
{
inputData();
process();
outputRes();
return 0;
}
多学习,多总结。

浙公网安备 33010602011771号