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