poj1025

//============================================================================
// Name        : 1025.cpp
// Author      : sww
// Version     : 1.0
// Time	       : 2013-11-15 14:47:40
//===========================================================================

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>

#define X 11
using namespace std;

typedef enum thingType {
	ENTRY,
	EXIT,
	WAIT_ELEVATOR,
	WAIT_ROOM,
	TRANFER_FROM_ROOM_TO_ROOM,
	TRANFER_FROM_ELEVATOR_TO_ROOM,
	TRANFER_FROM_ROOM_TO_ELEVATOR,
	STAY_IN_ROOM,
	STAY_IN_ELEVATOR,

	TRY_ELEVATOR,
	TRY_ROOM
} ThingType;

typedef struct room {
	int floor;
	int room_number;
} Room;

typedef struct visit {
	Room rm;
	int period;
} Visit;

class Data;

typedef struct thing {
	int number;
	int start;
	int end;
	ThingType type;
	Room rm1;
	Room rm2;
	Data * data;
	int period;

	friend bool operator<(const struct thing& a, const struct thing& b) {
		if (a.start != b.start)
			return a.start > b.start;
		return a.number > b.number;
	}
} Thing;

class Data {
private:
	//for input
	int start;
	int number;
	vector<Visit> visits;

	//for out
	vector<Thing> things;
	int nextThing;
	int time;
public:
	Data(int number);
	int getNumber() const;
	void handleThing(const Thing& th);
	void output();
};

class Elevator {
private:
	int time;
public:
	Elevator();
	int useElevator(int start);
};

class UseElevator {
private:
	Elevator eles[X];
public:
	int useElevator(int start, int floor);
};
class ARoom {
private:
	int time;
public:
	ARoom();
	int useARoom(int start, int period);
};

class UseRoom {
private:
	ARoom eles[X][X];
public:
	int useRoom(const Room& rm, int start, int period);
};

int cmp(const Data* a, const Data* b) {
	if (a->getNumber() < b->getNumber())
		return 1;
	return 0;
}

void outputTime(const int& time) {
	int s = time % 60;
	int h = time / 3600;
	int m = time / 60 % 60;
	printf("%2.2d:%2.2d:%2.2d ", h, m, s);
}

void outputRoom(const Room& rm) {
	printf("%2.2d%2.2d", rm.floor, rm.room_number);
}

int toFive(const int& a) {
	if (a % 5 == 0) {
		return a;
	} else {
		return a + (5 - a % 5);
	}
}

void outputThing(const Thing& th) {
	outputTime(th.start);
	outputTime(th.end);
	switch (th.type) {
	case ENTRY:
		puts("Entry");
		break;
	case EXIT:
		puts("Exit");
		break;
	case WAIT_ELEVATOR:
		puts("Waiting in elevator queue");
		break;
	case WAIT_ROOM:
		printf("Waiting in front of room ");
		outputRoom(th.rm1);
		puts("");
		break;
	case TRANFER_FROM_ROOM_TO_ROOM:
		printf("Transfer from room ");
		outputRoom(th.rm1);
		printf(" to room ");
		outputRoom(th.rm2);
		puts("");
		break;
	case TRANFER_FROM_ELEVATOR_TO_ROOM:
		printf("Transfer from elevator to room ");
		outputRoom(th.rm1);
		puts("");
		break;
	case TRANFER_FROM_ROOM_TO_ELEVATOR:
		printf("Transfer from room ");
		outputRoom(th.rm1);
		puts(" to elevator");
		break;
	case STAY_IN_ELEVATOR:
		puts("Stay in elevator");
		break;
	case STAY_IN_ROOM:
		printf("Stay in room ");
		outputRoom(th.rm1);
		puts("");
		break;
	}
}

priority_queue<Thing> q;
UseElevator elevator;
UseRoom ur;

int main() {
	char c;
	vector<Data*> das;
	while (1) {
		scanf("%c", &c);
		if (c == '.')
			break;
		Data * d = new Data(c - 'A');
		das.push_back(d);
	}
	sort(das.begin(), das.end(), cmp);
	while (!q.empty()) {
		Thing th = q.top();
		q.pop();
		th.data->handleThing(th);
	}
	for (vector<Data*>::iterator it = das.begin(); it != das.end(); ++it) {
		(*it)->output();
	}
	return 0;
}

/***********************
 * class Data
 **********************/
Data::Data(int number) {
	this->number = number;
	int h, m, s;
	scanf("%d:%d:%d", &h, &m, &s);
	start = h * 3600 + m * 60 + s;
	Visit v;
	int temp;
	while (1) {
		scanf("%d", &temp);
		if (temp == 0) {
			getchar();
			break;
		}
		scanf("%d", &v.period);
		v.rm.floor = temp / 100;
		v.rm.room_number = temp % 100;
		visits.push_back(v);
	}

	nextThing = 0;
	time = start;

	Thing th;
	th.start = time;
	time += 30;
	th.end = time;
	th.type = ENTRY;
	things.push_back(th);

	Thing nth;
	nth.data = this;
	Visit &vs = visits[nextThing];
	if (vs.rm.floor == 1) {
		nth.start = time;
		nth.type = TRY_ROOM;
		nth.period = vs.period;
		nth.rm1 = vs.rm;
	} else {
		nth.start = toFive(time);
		nth.rm1.floor = 1;
		nth.type = TRY_ELEVATOR;
		nth.period = 30 * (vs.rm.floor - 1);
	}
	nth.number = number;
	q.push(nth);
}

int Data::getNumber() const {
	return number;
}

void Data::handleThing(const Thing& th) {
	if (th.type == TRY_ELEVATOR) {
		int st = elevator.useElevator(th.start, th.rm1.floor);
		if (st != time) {
			Thing nth;
			nth.start = time;
			nth.end = st;
			nth.type = WAIT_ELEVATOR;
			things.push_back(nth);
			time = st;
		}

		Thing nth;
		nth.start = time;
		time += th.period;
		nth.end = time;
		nth.type = STAY_IN_ELEVATOR;
		things.push_back(nth);

		if (nextThing < visits.size()) {
			Visit& vt = visits[nextThing];
			nth.start = time;
			time += 10;
			nth.end = time;
			nth.type = TRANFER_FROM_ELEVATOR_TO_ROOM;
			nth.rm1 = vt.rm;
			things.push_back(nth);

			nth.start = time;
			nth.data = this;
			nth.type = TRY_ROOM;
			nth.period = vt.period;
			nth.rm1 = vt.rm;
			nth.number = number;
			q.push(nth);
		} else {
			nth.start = time;
			time += 30;
			nth.end = time;
			nth.type = EXIT;
			things.push_back(nth);
		}
	} else if (th.type == TRY_ROOM) {
		int st = ur.useRoom(th.rm1, th.start, th.period);
		if (st != time) {
			Thing nth;
			nth.start = time;
			nth.end = st;
			nth.type = WAIT_ROOM;
			nth.rm1 = th.rm1;
			things.push_back(nth);
			time = st;
		}

		Thing nth;
		nth.start = time;
		time += th.period;
		nth.end = time;
		nth.type = STAY_IN_ROOM;
		nth.rm1 = th.rm1;
		things.push_back(nth);

		nextThing++;
		if (nextThing < visits.size()) {
			Visit& vt = visits[nextThing];
			if (vt.rm.floor == th.rm1.floor) { //同一层
				nth.start = time;
				time += 10;
				nth.end = time;
				nth.type = TRANFER_FROM_ROOM_TO_ROOM;
				nth.rm1 = th.rm1;
				nth.rm2 = vt.rm;
				things.push_back(nth);

				nth.start = time;
				nth.data = this;
				nth.type = TRY_ROOM;
				nth.period = vt.period;
				nth.rm1 = vt.rm;
				nth.number = number;
				q.push(nth);
			} else {
				nth.start = time;
				time += 10;
				nth.end = time;
				nth.type = TRANFER_FROM_ROOM_TO_ELEVATOR;
				things.push_back(nth);

				nth.start = toFive(time);
				nth.data = this;
				nth.type = TRY_ELEVATOR;
				nth.rm1.floor = th.rm1.floor;
				nth.period = 30 * (vt.rm.floor - th.rm1.floor);
				nth.number = number;
				q.push(nth);
			}
		} else {
			if (th.rm1.floor == 1) {
				nth.start = time;
				time += 30;
				nth.end = time;
				nth.type = EXIT;
				things.push_back(nth);
			} else {
				nth.start = time;
				time += 10;
				nth.end = time;
				nth.type = TRANFER_FROM_ROOM_TO_ELEVATOR;
				things.push_back(nth);

				nth.start = toFive(time);
				nth.data = this;
				nth.type = TRY_ELEVATOR;
				nth.rm1.floor = th.rm1.floor;
				nth.period = 30 * (th.rm1.floor - 1);
				nth.number = number;
				q.push(nth);
			}
		}
	}
}

void Data::output() {
	printf("%c\n", number + 'A');
	for (vector<Thing>::const_iterator it = things.begin(); it != things.end();
			++it) {
		outputThing(*it);
	}
	puts("");
}
/***********************
 * class Elevator
 **********************/
int Elevator::useElevator(int start) {
	if (start < time) {
		int re = time;
		time += 5;
		return re;
	} else {
		time = start + 5;
		return start;
	}
}

Elevator::Elevator() {
	time = 0;
}

/***********************
 * class UseRoom
 **********************/
int UseRoom::useRoom(const Room& rm, int start, int period) {
	return eles[rm.floor][rm.room_number].useARoom(start, period);
}

/***********************
 * class ARoom
 **********************/
int ARoom::useARoom(int start, int period) {
	if (start < time) {
		int re = time;
		time += period;
		return re;
	} else {
		time = start + period;
		return start;
	}
}

ARoom::ARoom() {
	time = 0;
}
/***********************
 * class UseElevator
 **********************/
int UseElevator::useElevator(int start, int floor) {
	return this->eles[floor].useElevator(start);
}

猜你喜欢

转载自blog.csdn.net/swwlqw/article/details/16804083