大一寒假集训(9)---优先队列

大一寒假集训(9)—优先队列

知识点

定义一个priority_queue的方法为: priority_queue name;
//type通常为结构体
其中,type可以是任何基本类型或者容器,name为优先队 列的名字。 和queue不一样的是,priority_queue没有front()和back(), 而只能通过top()或pop()访问队首元素(也称堆顶元素),也 就是优先级最高的元素。

typedef long long LL; 
struct sa {LL x; LL y; LL sum; };
 LL a[400005],b[400005]; 
 bool operator < (const sa &a,const sa &b)
  { 
  return a.sum >b.sum;
  //表示的是从小到大 
  }

Priority_queue队列
大根堆:从大到小排列。 小根堆:从小到大排列。 优先队列就是堆,也可以自己手写堆。 //小根堆的写法 priority_queue<int,vector,greater > vis; //大根堆的写法 priority_queue<int,vector,less > vis;
当就是1个类型,可以这样直接写; 也可以用结构题。

1.合并果子-优先队列 nefu 1688

本题是典型的使用优先队列的题

#include <bits/stdc++.h>
using namespace std;
int n;
int x,ans;
int y2;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
    ans=0;
    cin>>n;
    for (int i=0;i<n;i++)
    {
        cin>>x;
        q.push(x);
    }
    while (q.size()>1)
    {
        int y1=q.top();
        q.pop();
        y2=q.top();
        q.pop();
        q.push(y1+y2);
        ans+=y1+y2;
    }
    cout<<ans;
    return 0;
}

2.合成陨石-优先队列 nefu 355

本题与第一题不同的是多组输入,记得初始化即可

#include <bits/stdc++.h>
using namespace std;
int n;
int x,ans;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
    while (cin>>n)
    {
        for (int i=0;i<n;i++)
        {
            cin>>x;
            q.push(x);
        }
        ans=0;//记得初始化
        while (q.size()>1)
        {
            int y1=q.top();
            q.pop();
            int y2=q.top();
            q.pop();
            q.push(y1+y2);
            ans+=y1+y2;
        }
        cout<<ans<<endl;
        q.pop();//初始化
    }
    return 0;
}

3.买饭-优先队列 nefu 1537

本题注意结构体自定义比较的方法

#include <bits/stdc++.h>
using namespace std;
int n;
int t;
double ans1,ans2;
struct que
{
    int t;//时间
    int num;//名字
};
bool operator < (const que &s1,const que &s2)
{
    if (s1.t!=s2.t)
        return s1.t>s2.t;
    else
        return s1.num>s2.num;
}
priority_queue<que,vector<que>  >q;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    ans1=0;
    ans2=0;
    for (int i=1;i<=n;i++)
    {
        cin>>t;
        q.push({t,i});
    }
    while (!q.empty())
    {
       que r=q.top();
       q.pop();
       ans1+=ans2;//总时间
       ans2+=r.t*1.0;//当前人的等待时间
       if (q.size()==0)
        cout<<r.num<<endl;
       else
        cout<<r.num<<" ";

    }
    printf("%.2lf\n",ans1/(1.0*n));

    return 0;
}

4.堆-优先队列 nefu 1692

基本操作,很简单的题

#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int>  >q;
int n;//n次操作
int main()
{
    ios::sync_with_stdio(false);//注意添加这一坨,不然会tle
    cin>>n;
    int x;//操作1 2 3
    int y;//输入的数
    for (int i=1;i<=n;i++)
    {
        cin>>x;
        if (x==1)
        {
            cin>>y;
            q.push(y);
        }
        if (x==2)
            cout<<q.top()<<endl;
        if(x==3)
            q.pop();
    }
    return 0;
}

5.瑞瑞的木板-优先队列 nefu 1691

与第一题类似

#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int>  >q;
int n;//木板数量
int x;
long long ans1;
int main()
{
    cin>>n;
    ans1=0;
    for (int i=1;i<=n;i++)
    {
        cin>>x;
        q.push(x);
    }
    while (q.size()>1)
    {
        int y1=q.top();
        q.pop();
        int y2=q.top();
        q.pop();
        q.push(y1+y2);
        ans1+=y1+y2;
    }
    cout<<ans1;
    return 0;
}
6.序列合并-优先队列 nefu 1689

详细题解如下
在这里插入图片描述
本题我应该一开始就听题目用scanf ,我用cin就一直tle

#include <bits/stdc++.h>
using namespace std;
int n,a[400005],b[400005];
struct lay
{
    int x;
    int y;
    long long ans;
};
bool operator < (const lay &s1,const lay &s2)
{
    return s1.ans>s2.ans;
}
priority_queue<lay,vector<lay> >q;
int main()
{
    //ios::sync_with_stdio(false);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        scanf("%d",&b[i]);
    for (int i=1;i<=n;i++)
        q.push({i,1,a[i]+b[1]});
    for (int i=1;i<=n;i++)
    {
        lay tmp=q.top();
        q.pop();
        printf("%lld\n",tmp.ans);
        int x0=tmp.x;
        int y0=tmp.y;
        q.push({x0,y0+1,a[x0]+b[y0+1]});

    }
    return 0;
}

7.桐桐的新闻系统-优先队列 nefu 1690
#include <bits/stdc++.h>
using namespace std;
char ch[10];
int id,t,k;
//int r1,r2;
struct lay
{
    int id;//名
    int t;//时间
    int  ans;//总时间
};
bool operator < (const lay &s1,const lay &s2)
{
    if (s1.ans!=s2.ans)
        return s1.ans>s2.ans;
    else return s1.id>s2.id;
}
priority_queue<lay,vector<lay> >q;
int main()
{
    ios::sync_with_stdio(false);
    while (cin>>ch&&ch[0]!='#')
    {
        cin>>id>>t;
        q.push({id,t,t});
    }
    cin>>k;//执行k次指令
    for (int i=1; i<=k; i++)
    {
        lay tmp=q.top();
        q.pop();
        cout<<tmp.id<<endl;
        q.push({tmp.id,tmp.t,tmp.ans+tmp.t});

    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值