Team Queue
Time Limit: Unknown Memory Limit: Unknown
Total Submission(s): Unknown Accepted Submission(s): Unknown
https://uva.onlinejudge.org/i...
Accepted Code
// Author : Weihao Long
// Created : 2018/01/17
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int QElemType;
struct QNode {
QElemType data;
struct QNode *next;
};
typedef struct {
QElemType team;
QNode *front;
QNode *rear;
}LinkQueue;
int InitQueue(LinkQueue *Q);
int EnQueue(LinkQueue *Q, QElemType e);
int DeQueue(LinkQueue *Q, QElemType *e);
int ClearQueue(LinkQueue *Q);
int DestroyQueue(LinkQueue *Q);
int people[1000007];
LinkQueue queue[1000007];
int main() {
int t;
int kase = 1;
while (scanf("%d", &t) != EOF) {
if (!t) {
break;
}
printf("Scenario #%d\n", kase++);
int m;
memset(people, 0, sizeof(people));
memset(queue, 0, sizeof(queue));
int qh = 1, qt = 1;
for (int i = 1; i <= t; i++) {
int cap;
scanf("%d", &cap);
while (cap--) {
scanf("%d", &m);
people[m] = i;
}
}
char cmd[10];
while (scanf("%s", cmd) != EOF) {
if (!strcmp(cmd, "STOP")) {
putchar('\n');
break;
}
else if (!strcmp(cmd, "ENQUEUE")) {
int flag = 0;
scanf("%d", &m);
int team = people[m];
for (int i = qh; i < qt; i++) {
if (queue[i].team == team) {
flag = i;
break;
}
}
if (flag) {
LinkQueue T;
T = queue[flag];
EnQueue(&T, m);
queue[flag] = T;
}
else {
LinkQueue T;
InitQueue(&T);
T.team = team;
EnQueue(&T, m);
queue[qt++] = T;
}
}
else if (!strcmp(cmd, "DEQUEUE")) {
LinkQueue T;
T = queue[qh];
DeQueue(&T, &m);
printf("%d\n", m);
queue[qh] = T;
if (T.front == T.rear)
qh++;
}
}
}
return 0;
}
int InitQueue(LinkQueue *Q) {
Q->front = Q->rear = (QNode *)malloc(sizeof(QNode));
if (!Q->front) {
exit(OVERFLOW);
}
Q->front->next = NULL;
return OK;
}
int EnQueue(LinkQueue *Q, QElemType e) {
QNode *p = (QNode *)malloc(sizeof(QNode));
if (!p) {
exit(OVERFLOW);
}
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
int DeQueue(LinkQueue *Q, QElemType *e) {
if (Q->front == Q->rear) {
return ERROR;
}
QNode *p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p) {
Q->rear = Q->front;
}
free(p);
return OK;
}
int ClearQueue(LinkQueue *Q) {
QNode *p, *q;
Q->rear = Q->front;
p = Q->front->next;
Q->front->next = NULL;
while (p) {
q = p;
p = p->next;
free(q);
}
return OK;
}
int DestroyQueue(LinkQueue *Q) {
while (Q->front) {
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
return OK;
}
Notes
题意:
团队排队,每次 ENQUEUE 先检查队伍里有没有自己人,若有,则插到自己人的最后,否则排到队尾。出队 DEQUEUE 按正常规则来。
思路:
1.用一个数组 queue 来存队列,队列中每个元素包含三个信息:团队编号、团队头指针、团队尾指针。并用 qh 标志队首,用 qt 标志队尾。
2.每次 ENQUEUE 先检查 queue 中有没有自己所属团队,若有,插到团队的最后。若没有,则在 queue 的最后新建一个团队,并插入这个人,然后把队尾标志后移。
3.每次 DEQUEUE 就把 queue 队首的团队中的第一个人输出,如果该团队空了,就把队首标志后移。
感受:
这题如果只用一个队列来做(队列中的元素包含两个信息:某人的编号、他所属团队),就需要便历整个队伍来查找自己所属团队,时间开销太大,过不了。
然后改进一下得到如上代码,用 queue 存团队编号以及该团队的头、尾指针,这样一来主队列大幅缩短,遍历的时间开销就大幅降低了。
附:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。