原题描述
问题描述
设停车场是一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。
基本要求
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。栈以顺序结构实现,队列以链表实现。
测试数据
设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3, 20), (‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,其中,‘A’表示到达;‘D’表示离去,‘E’表示输入结束。
实现提示
需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。输入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含两个数据项:汽车的牌照号码和进入停车场的时刻。
解题思路
实现提示上基本已经给了,主要的难点在于main函数中如何调用栈和队列。
car结构中TAG是车辆进入的次序,用以在输出的时候排序,enTime表示汽车在停车场内停留的时间。
直接看代码。主要看main函数。
参考代码
#include <iostream>
using namespace std;
#pragma region Car
struct Car
{
int TAG, EnTime;
Car() {}
Car(int tag, int enTime)
{
TAG = tag;
EnTime = enTime;
}
};
#pragma endregion
#pragma region SeqStack
#define MAXSIZE 100
class SeqStack
{
public:
SeqStack() { top = -1; StackSize = MAXSIZE; }
SeqStack(int stackSize) { top = -1; StackSize = stackSize; }
~SeqStack() {}
bool Push(Car* x);
Car* Pop();
Car* GetTop() { if (top != -1) return data[top]; }
int Empty()
{
if (top == -1)
return 1;
return 0;
}
private:
Car* data[MAXSIZE];
int top;
int StackSize;
};
bool SeqStack::Push(Car* x)
{
if (top == StackSize - 1)
{
cout << "ERROR, bigger than stack size";
return false;
}
data[++top] = x;
return true;
}
Car* SeqStack ::Pop()
{
if (top == -1)
{
return NULL;
}
Car* x;
x = data[top--];
return x;
}
#pragma endregion
#pragma region LinkQueue
struct Node
{
Car* data;
Node * next;
};
class LinkQueue
{
public:
LinkQueue();
~LinkQueue();
void EnQueue(Car* x);
Car* DeQueue();
int Empty() { return front == rear ? 1 : 0; }
private:
Node * front, *rear; // 队头和队尾指针,分别指向头结点和终端结点
};
LinkQueue::LinkQueue()
{
Node *s = new Node;
s->next = NULL;
front = rear = s;
}
LinkQueue::~LinkQueue()
{
Node *s, *t = new Node;
s = front;
t = rear;
delete s;
delete t;
}
void LinkQueue ::EnQueue(Car* x)
{
Node *s = new Node;
s->data = x;
s->next = NULL;
rear->next = s;
rear = s;
}
Car* LinkQueue::DeQueue()
{
if (rear == front) throw"下溢";
Node *s = new Node;
Car* x;
s = front->next;
x = s->data;
front->next = s->next;
if (s->next == NULL)
rear = front;
delete s;
return x;
}
#pragma endregion
int main()
{
char ch;
int tag, time, n;
cin >> n;
auto park = new SeqStack(n);
auto tempStack = new SeqStack;
auto road = new LinkQueue;
while (cin >> ch >> tag >> time, ch != 'E')
{
if (ch == 'A')
{
auto tempCar = new Car(tag, time);
if (!park->Push(tempCar))
{
cout << ". "<< tag << " can't enter park, cause park is full." << endl;
road->EnQueue(tempCar);
}
}
else if (ch == 'D')
{
auto popedCar = park->Pop();
while (popedCar->TAG != tag)
{
tempStack->Push(popedCar);
popedCar = park->Pop();
}
cout << "Car #" << popedCar->TAG << " leaves the park. Total time: " << time - popedCar->EnTime << endl;
delete popedCar;
// cars in temp stack reEnter the park
if (!tempStack->Empty())
{
popedCar = tempStack->Pop();
while (popedCar != NULL)
{
park->Push(popedCar);
popedCar = tempStack->Pop();
}
delete popedCar;
}
// if the road is not empty, car in road will enter park
if (!road->Empty())
{
popedCar = road->DeQueue();
popedCar->EnTime = time;
park->Push(popedCar);
}
}
}
return 0;
}