PTA-Windows消息队列-C语言(最小堆)

PTA-7-26 Windows消息队列

直达题目点我!>…<

题目描述就不写啦

思路

  1. 最小堆,堆顶就是最小的数字咯(也就是优先级最大的)
  2. 这样我们只需要创建一个最小堆,每次GET时将第一位输出就行了,然后将第一位删除(也就是让最后一位到第一位,当然这个时候,已经不是二叉堆了,就需要将堆顶的向下滚(down函数)…)
  3. 建立堆,也就是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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值