PTA-7-26 Windows消息队列
直达题目点我!>…<
题目描述就不写啦
思路
- 最小堆,堆顶就是最小的数字咯(也就是优先级最大的)
- 这样我们只需要创建一个最小堆,每次GET时将第一位输出就行了,然后将第一位删除(也就是让最后一位到第一位,当然这个时候,已经不是二叉堆了,就需要将堆顶的向下滚(down函数)…)
- 建立堆,也就是PUT时,只需要将每个输入进来的消息放在最后一位,然后up(就是让他向上滚),形成最小堆…(这里不了解最小堆的小伙伴可能理解起来很难,建议先把最小堆,最大堆的创建学一学QAQ)
这里说明一下up和down两个函数,是用来维护这个堆的,也就是使得这个堆永远是个最小堆(原谅我可能说明上可能有些名词是错de,但就是这意思…)
再说明下题目所述的消息队列,其实这个堆就是一个叫做优先队列的东东
AC代码(测试点3 59msQAQ)
#include <stdio.h>
#include <string.h>
struct queue{
char name[11];
int lev;
};
int n = 0;
struct queue que[100020];
//一维数组算法
//int top;
/*
void del(int k)
{
for(int i=k;i<top-1;i++)
que[i] = que[i+1];
top--;
}
int find_max()
{
int max = 0;
for(int i=1;i<top;i++)
if(que[i].lev < que[max].lev)
max = i;
return max;
}
int main()
{
scanf("%d",&n);
int i,max = 0;
for(i=0;i<n;i++)
{
char s[4];
scanf("%s",s);
//cin>>s;
if(strcmp(s,"PUT") == 0)
{
char s[10];
int l;
scanf("%s %d",s,&l);
que[top].name = s;
que[top].lev = l;
top++;
}
else if(strcmp(s,"GET") == 0)
{
if(top == 0)
printf("EMPTY QUEUE!\n");
else
{
max = find_max();
cout<<que[max].name<<endl;
del(max);
}
}
}
return 0;
}
*/
//最小堆
void swap(int x,int y)
{
struct queue t = que[x];
que[x] = que[y];
que[y] = t;
}
void up(int i)
{
while(i != 1)
{
if(que[i].lev < que[i/2].lev)
swap(i,i/2);
else
return ;
i/=2;
}
}
void down(int i)
{
int t = i;
while(i*2 <= n)
{
if(que[t].lev > que[i*2].lev)
t = i*2;
if(i*2 + 1<=n && que[t].lev > que[i*2+1].lev)
t = i*2 + 1;
if(t != i)
swap(t,i);
else
return ;
i = t;
}
}
int main()
{
int m;
scanf("%d",&m);
int i;
for(i=0;i<m;i++)
{
char s[4];
scanf("%s",s);
if(strcmp(s,"PUT") == 0)
{
int lv;
char s[11];
scanf("%s %d",s,&lv);
strcpy(que[++n].name,s);
que[n].lev = lv;
up(n);
}
else
{
if(n == 0)
printf("EMPTY QUEUE!\n");
else
{
printf("%s\n",que[1].name);
swap(1,n);
n--;//删除第一位
down(1);
}
}
}
return 0;
}
这里建议如果碰到运行超时,多使用C的语法输入输出,就不会超时辣(cout和cin是面向对象中的,虽然简单,但是耗时)
-----------------------------------------------------------------------------------end