Problem Description
refresh最近发了一笔横财,开了一家停车场。由于土地有限,停车场内停车数量有限,但是要求进停车场的车辆过多。当停车场满时,要进入的车辆会进入便道等待,最先进入便道的车辆会优先
进入停车场,而且停车场的结构要求只出去的车辆必须是停车场中最后进去的车辆。现告诉你停车场容量N以及命令数M,以及一些命令(Add num 表示车牌号为num的车辆要进入停车场或便道,
Del 表示停车场中出去了一辆车,Out 表示便道最前面的车辆不再等待,放弃进入停车场)。假设便道内的车辆不超过1000000.
Input
输入为多组数据,每组数据首先输入N和M(0< n,m <200000),接下来输入M条命令。
Output
输入结束后,如果出现停车场内无车辆而出现Del或者便道内无车辆而出现Out,则输出Error,否则输出停车场内的车辆,最后进入的最先输出,无车辆不输出。
Example Input
2 6
Add 18353364208
Add 18353365550
Add 18353365558
Add 18353365559
Del
Out
Example Output
18353365558
18353364208
Think: 一道队列的题,不过做起来是对两条链表进行操作的题。这题有两个小的坑点,或者说是自己起初对题目没理解好。一、如果停车场里出去一辆车(Del)and便道里有车,就要让便道里的车进到停车场里。我第一次做的时候对于Del操作只进行停车场最后一辆车出来的操作,结果提交直接Wrong Answer,还好看了题目给的样例,一下子就发现了这个问题。二、题目要求“输入结束后,如果出现停车场内无车辆而出现Del或者便道内无车辆而出现Out,则输出Error”,我一开始是在出现Del/Out操作不合法时就直接输出Error了,而这题的意思是如果M个操作中存在上述的不合法,在所有的M个指令结束后再“秋后算账”,没错,就是让你先记账、忍着,呵呵~另外这题最后要求停车场里的车,先进的先输出(没有Del/Out操作不合法的话)。由于我是用的单向链表实现的,所以一开始我是逆序建立链表,这样对于Del操作,只需要删除第一个节点就好。
好了,纯C代码如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct Lnode
{
char ch[1001000]; //存号码牌,开的字符串有点大,毕竟不确定号码牌会不会有开挂的长度。。。
struct Lnode *next;
}Lnode;
typedef struct
{
struct Lnode *front; //指向第一个节点之前
int length; //链表的长度
}Lqueue;
void InitLqueue(Lqueue *a); //初始化队列
void Add(Lqueue *a, char number[]); //加入一辆车,num字符串用于存车牌号码
void Del(Lqueue *a); //停车场最后一辆车出队列
void Out(Lqueue *a); //便道里第一辆车出队列
void Show(Lqueue *a); //按照先进先输出的顺序输出停车场里车辆的号码牌
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF){
int i, flag = 1;
Lqueue a, b;
InitLqueue(&a); //停车场的队列(链表)
InitLqueue(&b); //便道的队列(链表)
char s[100100], number[1001000];
for(i = 0; i < m; i++){
scanf("%s", s); //指令
if(strcmp(s, "Add") == 0){
scanf("%s", number);
if(a.length < n){ //如果停车场未满,车子直接进入停车场
Add(&a, number);
}
else if(b.length < 1000000){ //虽然题目有限定M数据大小,还是判断了一下
Add(&b, number); //停车场满了,车子进入便道
}
}
else if(strcmp(s, "Del") == 0){
if(!a.length){ //准备好指令不合法,准备“秋后算账”,哼~
flag = 0;
}
else{
Del(&a);
if(b.length){ //如果便道里有车等待,就放便道第一辆车进入停车场
Lnode *p = b.front->next;
while(p->next){
p = p->next;
}
strcpy(number, p->ch);
Add(&a, number); //该进的进
Out(&b); //该出的出
}
}
}
else if(strcmp(s, "Out") == 0){
if(!b.length){ //如果便道里无车辆等待,则操作不合法
flag = 0;
}
else Out(&b);
}
}
if(flag == 0) //存在指令不合法,秋后算账~
printf("Error\n");
else if(a.length){
Show(&a);
}
}
return 0;
}
void InitLqueue(Lqueue *a) //初始化队列
{
a->front = (Lnode *)malloc(sizeof(Lnode));
if(!a->front) exit(0); //如果建立失败,结束程序
a->front->next = NULL; //先让next--NULL,以防万一
a->length = 0;
}
void Add(Lqueue *a, char number[]) //车子进入停车场
{
Lnode *p = (Lnode *)malloc(sizeof(Lnode));
strcpy(p->ch, number); //复制车牌号
p->next = NULL;
p->next = a->front->next; //机智得逆序建立链表
a->front->next = p;
a->length++; //越是简单的操作越不能忽视
}
void Del(Lqueue *a) //停车场里最后一辆车子出列
{
Lnode *p = a->front->next;
a->front->next = p->next; //因为是逆序建立的,
free(p); //所以删除的“第一”一个节点就是最后一辆车子
a->length--;
}
void Out(Lqueue *a) //便道里第一辆车出列
{
Lnode *pr, *p = a->front->next;
pr = a->front;
while(p->next){ //因为便道里的车子也是逆序建立,所以要让第一辆等待的车子离开
pr =p; //要删除的实际上是链表的最后的节点
p = p->next;
}
pr->next = NULL;
free(p);
a->length--;
}
void Show(Lqueue *a) //输出停车场的车子的车牌号
{
Lnode *p = a->front->next;
while(p){
printf("%s\n", p->ch);
p = p->next;
}
}