2、停车场管理
[问题描述]
设停车场内只有一个可停放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’表示输入结束。
[基本要求]
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。栈以顺序结构实现,队列以链表实现。
[实现提示]
需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。输入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含两个数据项:汽车的牌照号码和进入停车场的时刻。
[选作内容]
(1) 两个栈共享空间,思考应开辟数组的空间是多少?
(2) 汽车可有不同种类,则它们的占地面积不同,收费标准也不同,如1辆客车和1.5辆小汽车的占地面积相同,1辆十轮卡车占地面积相当于3辆小汽车的占地面积。
(3) 汽车可以直接从便道上开走,此时排在它前面的汽车要先开走让路,然后再依次排到队尾。
(4) 停放在便道上的汽车也收费,收费标准比停放在停车场的车低,请思考如何修改结构以满足这种要求。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define PRICE 8
#define Stack_Size 50 //定义狭长通道最大容量车的个数
typedef struct car
{
char location;//车辆是到达还是出去
int password;//车牌号码
int time;//到达或出去的时间
}Car;
typedef struct
{
Car data[Stack_Size];
int top;//用来存栈顶元素的下标,top=-1表示为空栈
}SeqStack;
SeqStack* InitStack()//初始化返回一个已分配内存的指向SeqStack类型的指针。
{
SeqStack *S;
S=new SeqStack;
S->top=-1;
return S;
}
int StackEmpty(SeqStack *S)//如果栈为空返回1
{
if(S->top==-1) return 1;
else return 0;
}
int StackFull(SeqStack *S,int n)//如果栈满返回1
{
if(S->top==n-1) return 1;
else return 0;
}
int push(SeqStack *S,Car car)//进栈,并把car中的值赋给S->data[].
{
if(S->top==Stack_Size-1)
return 0;
S->top++;
S->data[S->top].location=car.location;
S->data[S->top].password=car.password;
S->data[S->top].time=car.time;
return 1;
}
int pop(SeqStack *S,Car car)//若找到了这个车,返回费用free。若没找到返回0;
{
if(S->top==-1)
return 0;
SeqStack *S1=InitStack();//定义一个顺序栈用来存放S栈中出的车.
int key=car.password;//定义要出去车辆的号码牌。
while(S->data[S->top].password!=key)//找车牌号为password的车,并把在password之前的车出到栈S1中。
{ push(S1,S->data[S->top]);
S->top--;
}
if(S->top==-1)
{
printf("没有这个车");
return 0;
}
else
{
int time1=S->data[S->top].time;//起始时间
S->top--;
int time2=car.time;
int free=(time2-time1)*PRICE; //计算价格
while(S1->top>=0)//车走了把S1中的车重新开入S
{
push(S,S1->data[S1->top]);
S1->top--;
}
return free;
}
}
/************* 完成 ***************/
/************* 栈的 **************/
/************* 初始 ***************/
/************* 化 ***************/
typedef struct Node
{
Car car;
struct Node *next;
int length;
}LinkQueueNode;
typedef struct
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
int InitQueue(LinkQueue *Q)//初始化队列链表
{
Q->front=new LinkQueueNode;
if(Q->front!=NULL)
{
Q->rear=Q->front;
Q->front->next=NULL;
Q->front->length=0;
return 1;
}
else return 0;
}
int EnterQueue(LinkQueue *Q,Car car)// 进入队列
{
LinkQueueNode *NewNode=new LinkQueueNode;
if(NewNode!=NULL)
{
NewNode->car.location=car.location;
NewNode->car.password=car.password;
NewNode->car.time=car.time;
Q->rear->next=NewNode;
Q->rear=NewNode;
Q->front->length++;
return 1;
}
else return 0;
}
Car DeleteQueue(LinkQueue *Q)//出队列,如果停车场不满把过道车停进停车场
{
LinkQueueNode *tt;//tt为第一个出队列的元素。
int time2;
tt=Q->front->next;
if(Q->rear==tt)
{ //Q->front->car.time=S->data[S->top].time;
Q->front->length--;
Q->rear=Q->front;
printf("请输入编号为%d的车出便道进入停车场的时间\n",tt->car.password);
scanf("%d",&time2);
tt->car.time=time2;
return tt->car;
free(tt);
}
else
{
Q->front->length--;
Q->front->next=tt->next;
printf("请输入编号为%d的车出便道进入停车场的时间\n",tt->car.password);
scanf("%d",&time2);
tt->car.time=time2;
return tt->car;
free(tt);
}
}
int LinkQueueEmpty(LinkQueue *Q)//如果队列是空的返回1
{
if(Q->front==Q->rear) return 1;
else return 0;
}
/************* 完成 ***************/
/************* 队列的 **************/
/************* 初始 ***************/
/************* 化 ***************/
int main()
{ int n;
Car cars;
SeqStack *Paking= InitStack();//建停车场的栈并初始化
LinkQueue CrossingRoad;//
InitQueue(&CrossingRoad);//建人行道的队列并初始化
printf("*******************停车管理系统*******************\n");
printf("*******************现有功能***********************\n");
printf("********** ①车辆进入*********************\n");
printf("********** ②车辆开出收费金额及停留时间*******\n");
printf("********** ③在便道上等候的车辆***********\n");
printf("***④车辆信息*第一项到达or离开*A表示到达*D表示****\n");
printf("********* 第二项车的编号 ***********\n");
printf("********* 第三项到达或离开的时间 ***********\n");
printf("请输入停车场最大能容纳车辆的总数\n");
scanf("%d",&n);
while(1)
{ printf("请输入车辆信息\n");
scanf("%c,%d,%d",&cars.location,&cars.password,&cars.time);
switch(cars.location)
{
case 'A':{ if(StackFull(Paking,n)==0)//栈未满
{
push(Paking,cars);
printf("这是停车场的第%d辆车\n",Paking->top+1);
}
else // 栈满了
{
EnterQueue(&CrossingRoad,cars);
printf("这是便道上的第%d辆车\n",CrossingRoad.front->length);
}
break;
}
case 'D' : {
int free=pop(Paking,cars);
int t=free/ PRICE;
printf("编号为%d停留的时间为%dhour,这辆车的收费为%d元\n",cars.password,t,free);
if(!StackFull(Paking,n))
{
if(!LinkQueueEmpty(&CrossingRoad))
{
push(Paking,DeleteQueue(&CrossingRoad));
}
break;
}
}
}
}
}