Отримання знань

дистанційна підтримка освіти школярів


Отдел
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;
}

 

Попередня Зміст Наступна
В системі: гості - (); користувачі - (0)