http://acm.pku.edu.cn/JudgeOnline/problem?id=1025

Код:
#include <queue>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

inline string NumToStr(int n)
{
    string str;
    str=(char)(n/10)+'0';
    str+=(char)(n%10)+'0';
    return str;
}

struct TIME
{
    char hour;
    char minu;
    char sec;
    TIME(char _hour=0,char _minu=0,char _sec=0)
    {
        hour=_hour;minu=_minu;sec=_sec;
    }
    void set(char _hour,char _minu,char _sec)
    {
        hour=_hour;minu=_minu;sec=_sec;
    }
    void Add(int secAdd)
    {
        int minAdd=((int)sec+secAdd)/60;
        sec=((int)sec+secAdd)%60;
        int houAdd=((int)minu+minAdd)/60;
        minu=((int)minu+minAdd)%60;
        hour=((int)hour+houAdd);
    }
    bool operator <(const TIME& t) const
    {
        return hour<t.hour||hour==t.hour&&minu<t.minu||hour==t.hour&&minu==t.minu&&sec<t.sec;
    }
    bool operator ==(const TIME& t) const
    {
        return hour==t.hour&&minu==t.minu&&sec==t.sec;
    }
    string ToString()
    {
        string str;
        str=NumToStr(hour%24);
        str+=":";
        str+=NumToStr(minu);
        str+=":";
        str+=NumToStr(sec);
        return str;
    }
    void FromString(string str)
    {
        int i=0;
        hour=(str.data()[i]-'0')*10+(str.data()[i+1]-'0');
        i+=3;
        minu=(str.data()[i]-'0')*10+(str.data()[i+1]-'0');
        i+=3;
        sec=(str.data()[i]-'0')*10+(str.data()[i+1]-'0');
    }
};
string GetRoomName(int floor,int roomId)
{
    string str;
    str=NumToStr(floor);
    str+=NumToStr(roomId);
    return str;
}
inline void GetRoomNum(int& floor,int& roomId,string str)
{
    floor=(str.data()[0]-'0')*10+(str.data()[1]-'0');
    roomId=(str.data()[2]-'0')*10+(str.data()[3]-'0');
}
 
struct Event
{
    int floor;
    TIME tmStart;
    TIME tmEnd;
    virtual string Name()=0;
};
struct EvWaitInQ:public Event
{
    int nRoomId;
    EvWaitInQ(TIME _tmStart,int _floor,int _nRoomId)
    {
        tmEnd=tmStart=_tmStart;
        floor=_floor;
        nRoomId=_nRoomId;
    }
    string Name()
    {
        string str=tmStart.ToString();
        str+=" ";
        str+=tmEnd.ToString();
        str+=" ";
        if(nRoomId==0) 
            str+="Waiting in elevator queue";
        else
        {
            str+="Waiting in front of room ";
            str+=GetRoomName(floor,nRoomId);
        }
        return str;
    }
};
struct EvTransfer:public Event
{
    int nRoomIdFrom,nRoomIdTo;
    EvTransfer(TIME _tmStart,int _floor,int _nRoomIdFrom,int _nRoomIdTo)
    { 
        nRoomIdFrom=_nRoomIdFrom;
        nRoomIdTo=_nRoomIdTo;
        
        tmEnd=tmStart=_tmStart;
        if (nRoomIdFrom==-1||nRoomIdTo==-1) 
            tmEnd.Add(30);
        else tmEnd.Add(10);
        floor=_floor;
    }
    string Name()
    {
        string str=tmStart.ToString();
        str+=" ";
        str+=tmEnd.ToString();
        str+=" ";
         
        if (nRoomIdFrom==-1||nRoomIdTo==-1)
        { 
            if (nRoomIdFrom==-1)
                str+="Entry";
            else str+="Exit";
            return str;
        }
         
        str+="Transfer from ";
        if(nRoomIdFrom==0) 
            str+="elevator";
        else
            str+="room "+GetRoomName(floor,nRoomIdFrom);
        str+=" to ";
        if(nRoomIdTo==0) 
            str+="elevator";
        else
            str+="room "+GetRoomName(floor,nRoomIdTo);
        return str;
    }
};
struct EvStay:public Event
{
    int nRoomId;
    EvStay(TIME _tmStart,int floorFrom,int floorTo,int _nRoomId)
    { 
        floor=floorFrom;
        tmEnd=tmStart=_tmStart;
        nRoomId=_nRoomId;
    }
    string Name()
    {
        string str=tmStart.ToString();
        str+=" ";
        str+=tmEnd.ToString();
        str+=" ";
        
        str+="Stay in ";
        if (nRoomId==0)
            str+="elevator";
        else
            str+="room "+GetRoomName(floor,nRoomId);
        return str;
    }
};
 
struct Task
{
    int floor,roomId; 
    int nTmLen; 
};
 
enum AGSTAT{ENTRY,GOTOROOM,GOTOQ,COMPLETE};
struct Agent
{
    int index; 
    AGSTAT stat;
    char ID;
    int curFloor; 
    TIME tmCur; 
    vector<Event*> vecEvent; 
    queue<Task> QTask; 
    bool operator <(const Agent& ag) const
    {
        return ID<ag.ID;
    }
    bool Init()
    { 
        if (!(cin>>ID)||ID=='.')
            return false;
        string str;
        cin>>str;
        tmCur.FromString(str);
        InitQTask();
        curFloor=1;
        stat=ENTRY;
        return true;
    }
    void InitQTask();
   
    void CheckTask();
    void Entry();
    void GoToQ();
    void GoToRoom();
    void Transfer(Task& laskTask);
    void Print();
};
vector<Agent> vecAg;
struct AgIDLess
{
    bool operator()(const int& ag1,const int& ag2)
    {
        return vecAg[ag1].ID>vecAg[ag2].ID;
    }
};
struct AgTimeIDLess
{
    bool operator()(const int& ag1,const int& ag2)
    {
        return vecAg[ag2].tmCur<vecAg[ag1].tmCur||
            vecAg[ag1].tmCur==vecAg[ag2].tmCur&&vecAg[ag1].ID>vecAg[ag2].ID;
    }
};
struct AgFloorLess
{
    bool operator()(const int& ag1,const int& ag2)
    {
        return vecAg[ag1].curFloor>vecAg[ag2].curFloor;
    }
};
struct Room
{
    TIME tmCur;
    priority_queue<int,vector<int>,AgIDLess> QWait;
    int Pop()
    { 
        int i=QWait.top();
        vecAg[i].tmCur=vecAg[i].vecEvent[vecAg[i].vecEvent.size()-1]->tmEnd=tmCur;
        QWait.pop();
        return i;
    }
};
 
Room room[11]; 
priority_queue<int,vector<int>,AgTimeIDLess> QAgWait; 
priority_queue<int,vector<int>,AgFloorLess> QAgOthflo; 
int curProcFloor;
 
void Agent::InitQTask()
{
    while (!QTask.empty())
        QTask.pop();
    char buffer[50]={0};
    Task lastTask;bool bFirst=true;
    while(scanf("%s",buffer)&&buffer[1]!=0)
    {
        Task task;
        GetRoomNum(task.floor,task.roomId,buffer);
        scanf("%d",&task.nTmLen);
        if (bFirst)
        {
            bFirst=false;
            if (task.floor!=1)
            {
                lastTask.floor=task.floor;lastTask.roomId=0;lastTask.nTmLen=abs(task.floor-1)*30;
                QTask.push(lastTask);
            }
        }
        else
        {
            if(lastTask.floor!=task.floor)
            {
                lastTask.nTmLen=abs(lastTask.floor-task.floor)*30;
                lastTask.floor=task.floor;lastTask.roomId=0;
                QTask.push(lastTask);
            }
        }
        QTask.push(task);
        lastTask=task;
    }
    if (lastTask.floor!=1)
    {
        lastTask.nTmLen=abs(lastTask.floor-1)*30;
        lastTask.floor=1;lastTask.roomId=0;
        QTask.push(lastTask);
    }
    lastTask.floor=1;lastTask.nTmLen=0;lastTask.roomId=-1;
    QTask.push(lastTask);
}
 
void Agent::CheckTask()
{ 
    switch(stat)
    {
    case ENTRY:
        Entry();
        break;
    case GOTOROOM:
        GoToRoom();
        break;
    case GOTOQ:
        GoToQ();
        break;
    case COMPLETE:
        break;
    default:
        break;
    }
}
void Agent::Entry()
{
    stat=GOTOQ;
    vecEvent.push_back(new EvTransfer(tmCur,1,-1,-1));
    tmCur.Add(30);
    QAgWait.push(index);
}
void Agent::GoToQ()
{ 
    Task task=QTask.front();
    if(task.floor!=curProcFloor&&task.roomId!=0)
    {
        QAgOthflo.push(index); 
        return;
    }
    stat=GOTOROOM;
     
    if (task.roomId==0&&room[task.roomId].QWait.empty()&&
        ((tmCur.sec%5)||tmCur<room[task.roomId].tmCur))
    { 
        room[task.roomId].tmCur=tmCur;
        room[task.roomId].tmCur.Add(5-tmCur.sec%5);
        vecEvent.push_back(new EvWaitInQ(tmCur,task.floor,task.roomId));
        room[task.roomId].QWait.push(index);
    }
    else if (room[task.roomId].QWait.empty()&&!(tmCur<room[task.roomId].tmCur)||
        !room[task.roomId].QWait.empty()&&*this<vecAg[room[task.roomId].QWait.top()]&&tmCur==room[task.roomId].tmCur) 
    {
        room[task.roomId].tmCur=tmCur;
        GoToRoom();
    }
    else
    {
        vecEvent.push_back(new EvWaitInQ(tmCur,task.floor,task.roomId));
        room[task.roomId].QWait.push(index);
    }
}
void Agent::GoToRoom()
{
    Task task=QTask.front();
    QTask.pop();
    vecEvent.push_back(new EvStay(tmCur,curFloor,task.floor,task.roomId));
    tmCur.Add(task.nTmLen); 
    vecEvent[vecEvent.size()-1]->tmEnd=tmCur; 
     
    if(task.roomId)
        room[task.roomId].tmCur.Add(task.nTmLen);
    else  
        room[task.roomId].tmCur.Add(5);
    curFloor=task.floor; 
    
    Transfer(task);
}
void Agent::Transfer(Task& laskTask)
{
    Task task=QTask.front();
    vecEvent.push_back(new EvTransfer(tmCur,laskTask.floor,laskTask.roomId,task.roomId));
    if (task.roomId==-1)
    { 
        tmCur.Add(30);
        QTask.pop();
        stat=COMPLETE;
    }
    else
    { 
        tmCur.Add(10);
        stat=GOTOQ;
        QAgWait.push(index);
    }
}
void Agent::Print()
{
    printf("%c\n",ID);
    for (int i=0;i<vecEvent.size();i++)
    {
        string str=vecEvent[i]->Name();
        delete vecEvent[i];
        printf("%s\n",str.c_str());
    }
    printf("\n");
    vecEvent.clear();
}
 
int GetRoom()
{
    int index=-1;
    TIME tm;
    for (int i=0;i<11;i++)
    {
        if (room[i].QWait.empty())
            continue;
        if (index==-1)
        {
            tm=room[i].tmCur;
            index=i;
        }
        else
        {
            if (room[i].tmCur<tm)
            {
                tm=room[i].tmCur;
                index=i;
            }
        }
    }
    return index;
}
void PrintAll()
{
    for (int i=0;i<vecAg.size();i++)
        vecAg[i].Print();
}
void MainProc()
{
    curProcFloor=1;
    for(int i=0;i<vecAg.size();i++)
    { 
        vecAg[i].CheckTask();
    }
    for(int i=0;i<11;i++)
        room[i].tmCur.set(0,0,0);
    while(1)
    {
        int nRoomIdx=GetRoom();
        if (nRoomIdx==-1&&QAgWait.empty())
        { 
            if (QAgOthflo.empty())
            { 
                PrintAll();
                return;
            }
             
            int i;
            do {
                i=QAgOthflo.top();
                QAgOthflo.pop();
                QAgWait.push(i);
            }while (!QAgOthflo.empty()&&vecAg[QAgOthflo.top()].curFloor==vecAg[i].curFloor);
            curProcFloor=vecAg[i].curFloor;
            for(int i=0;i<11;i++)
                room[i].tmCur.set(0,0,0);
        }
        else if (QAgWait.empty()||nRoomIdx!=-1&&room[nRoomIdx].tmCur<vecAg[QAgWait.top()].tmCur)
        { 
            int index=room[nRoomIdx].Pop();
            vecAg[index].CheckTask();
        }
        else
        { 
            int index=QAgWait.top();
            QAgWait.pop();
            vecAg[index].CheckTask();
        }
    }
}

int main(int argc, char* argv[])
{
    Agent ag;
    while (ag.Init())
    {
        vecAg.clear();
        do
        {
            vecAg.push_back(ag);
        }while(ag.Init());
        sort(vecAg.begin(),vecAg.end());
        for(int i=0;i<vecAg.size();i++)
            vecAg[i].index=i;
        MainProc();
        break;
    }
    return 0;
}