消息队列是Windows系统的基础。对于每个进程,系统维护一个消息队列。如果在进程中有特定事件发生,如点击鼠标、文字改变等,系统将把这个消息加到队列当中。同时,如果队列不是空的,这一进程循环地从队列中按照优先级获取消息。请注意优先级值低意味着优先级高。请编辑程序模拟消息队列,将消息加到队列中以及从队列中获取消息。
输入格式:
输入首先给出正整数N(≤105),随后N行,每行给出一个指令——GET
或PUT
,分别表示从队列中取出消息或将消息添加到队列中。如果指令是PUT
,后面就有一个消息名称、以及一个正整数表示消息的优先级,此数越小表示优先级越高。消息名称是长度不超过10个字符且不含空格的字符串;题目保证队列中消息的优先级无重复,且输入至少有一个GET
。
输出格式:
对于每个GET
指令,在一行中输出消息队列中优先级最高的消息的名称和参数。如果消息队列中没有消息,输出EMPTY QUEUE!
。对于PUT
指令则没有输出。
输入样例:
9
PUT msg1 5
PUT msg2 4
GET
PUT msg3 2
PUT msg4 4
GET
GET
GET
GET
输出样例:
msg2
msg3
msg4
msg1
EMPTY QUEUE!
本题我尝试了三种思路;前两种就是简单了当的使用队列分别进行插入排序/快速排序,但是最后一个测试点都是运行超时;
第三种思路用了最小堆终于过了;还是最小堆牛啊,快速排序都被干掉了。。。不过我也是闲的蛋疼才分别使用了两种不同的排序算法。。
我把前两种也记录一下,当作一个小教训吧。简单粗暴的算法已经没法满足PAT了。。
//思路一 在入队那一块进行插入排序 测试点三大数据运行超时
typedef struct{
char data[10];
int info;
}node;//将优先级以及消息信息打包起来
typedef struct{
node nodes[MAXSIZE];
int head;
int tail;
}QUQUE;//装成队列
int isEmpty(QUQUE *q)
{
if(q->head==q->tail)return 1;
return 0;
}
void delet(QUQUE *q)
{
if(isEmpty(q))
{
printf("EMPTY QUEUE!\n");
return;
}
printf("%s\n",q->nodes[q->head++].data);
}
void add(QUQUE *q,char *data,int info)
{
int i=0;
node t;
strcpy(t.data,data);t.info=info;
if(q->tail==0)
{
q->nodes[0]=t;
}
//类似于插入排序 寻找比它优先级低的 找到直接插入
else
{
for(i=q->tail;i>q->head&&info<q->nodes[i-1].info;i--)
{
q->nodes[i]=q->nodes[i-1];
}
q->nodes[i]=t;
}
q->tail++;
}
//思路二 出队的时候再进行排序,采用快速排序 测试点三大数据情况同样超时
typedef struct{
char data[10];
int info;
}node;//将优先级以及消息信息打包起来
typedef struct{
node nodes[MAXSIZE];
int head;
int tail;
}QUQUE;//装成队列
int isEmpty(QUQUE *q)
{
if(q->head==q->tail)return 1;
return 0;
}
void Qsort(QUQUE *q,int left,int right)
{
if(left>=right) //直接跳出
return;
int i,j;
i=left;j=right;
node t,flag=q->nodes[left];//作为参考数
while(i!=j)
{
while(q->nodes[j].info>=flag.info&&i<j)
j--;
while(q->nodes[i].info<=flag.info&&i<j)
i++;
if(i<j)
{
t=q->nodes[i];
q->nodes[i]=q->nodes[j];
q->nodes[j]=t;
}
}
q->nodes[left]=q->nodes[i]; //这里是把左端归位
q->nodes[i]=flag; //这里是把参考数归位
Qsort(q,left,i-1); //处理左半部分
Qsort(q,i+1,right); //处理右半部分
}
//在出队这里采用快速排序
void delet(QUQUE *q)
{
if(isEmpty(q))
{
printf("EMPTY QUEUE!\n");
return;
}
Qsort(q,q->head,q->tail-1);
printf("%s\n",q->nodes[q->head++].data);
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100010
//思路三 用最小堆,大测试数据终于AC
typedef struct{
char data[16];
int info;
}node;//将优先级以及消息信息打包起来
typedef struct{
node nodes[MAXSIZE];
int size;//堆的元素个数
}HEAP;//装成队列
int isEmpty(HEAP *h)
{
if(h->size==0)return 1;
return 0;
}
void delet(HEAP *h)
{
if(isEmpty(h))
{
printf("EMPTY QUEUE!\n");
return;
}
int dad,child;
node MINTEMP,TEMP;
MINTEMP=h->nodes[1];//取出优先级最高的
printf("%s\n",MINTEMP.data);
TEMP=h->nodes[h->size--];
for(dad=1;dad*2<h->size;dad=child)
{
child=dad*2;
if(child+1<=h->size&&h->nodes[child+1].info<h->nodes[child].info)child++;
if(TEMP.info<h->nodes[child].info)break;
else
h->nodes[dad]=h->nodes[child];
}
h->nodes[dad]=TEMP;
}
void add(HEAP *h,char *data,int info)
{
node t;strcpy(t.data,data);t.info=info;
int i;
for(i=++h->size;t.info<h->nodes[i/2].info;i/=2)
{
h->nodes[i]=h->nodes[i/2];
}
h->nodes[i]=t;
}
int main()
{
HEAP *h=(HEAP*)malloc(sizeof(HEAP));
h->size=0;h->nodes[0].info=-1;
int n,info,i;
char tips[5],msg[16];
scanf("%d",&n);getchar();
for(i=0;i<n;i++)
{
scanf("%s",tips);
if(strcmp(tips,"PUT")==0)
{
scanf("%s%d",msg,&info);
add(h,msg,info);
}
else if(strcmp(tips,"GET")==0)
{
delet(h);
}
}
return 0;
}