2020.2.13 大一寒假训练八(优先队列)

Problem A:NEFU1537 买饭

结构体,重载运算符

#include<bits/stdc++.h>
using namespace std;
struct node{
    int t, No;
};
priority_queue<node, vector<node> > q;
bool operator < (const node &s1, const node &s2)
{
    if(s1.t != s2.t) return s1.t > s2.t;
    else return s1.No > s2.No;
}
int n, every_time;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>every_time;
        q.push({every_time, i});
    }
    int ans=0, tmp=n;
    while(!q.empty())
    {
        n--;
        if(q.size() > 1)
            cout<<q.top().No<<" ";
        else cout<<q.top().No<<endl;
        ans += (q.top().t)*n;
        q.pop();
    }
    printf("%.2lf", ans*1.0/tmp);
    return 0;
}

Problem B:NEFU1688 合并果子

可以用堆也可以贪心
(优先队列stl的本质就是堆)

#include<bits/stdc++.h>
using namespace std;
priority_queue<int, vector<int>, greater<int> > q;
int main()
{
    ios::sync_with_stdio(false);
    int n, i, ans=0;
    cin>>n;
    while(n--)
    {
        cin>>i;
        q.push(i);
    }
    while(q.size() > 1)
    {
        int t1=q.top();
        q.pop();
        int t2=q.top();
        q.pop();
        ans += t1+t2;
        q.push(t1+t2);
    }
    cout<<ans<<endl;
    return 0;
}

Problem C:NEFU1689 序列合并

由于所给数据保证a, b均有序,所以 a[1]+b[1]必定最小。
a[i]+b[1]a[1]+b[i]大小均递增

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
    ll No, sum;
};
priority_queue<node, vector<node> > q;
bool operator < (const node &nod1, const node &nod2)
{
    return nod1.sum > nod2.sum;
}
ll a[400005], b[400005];
int c[400005]; // 用来求和
int main()
{
    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld", &a[i]);
        c[i] = 1; // 先将下标定位为1
    }
    for(int i=1; i<=n; i++)
        scanf("%lld", &b[i]);
    for(int i=1; i<=n; i++)
        q.push({i, a[i]+b[1]}); // 先a[i]+b[1]
    for(int i=1; i<=n; i++)
    {
        node tmp = q.top();
        printf("%lld\n", tmp.sum); // a[1]+b[1]必最小
        c[tmp.No]++; // 下标累加
        q.pop();
        tmp.sum = a[tmp.No]+b[c[tmp.No]]; // 更新
        q.push(tmp);
    }
    return 0;
}

Problem D:NEFU355 合成陨石

本题为多组输入,所以应注意每次的清空。
可以在while循环里申请队列,也可以每次操作完后清空队列(由于队列操作结束之后只剩下一个元素,所以直接pop掉即可)。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int n, i, ans=0;
    while(cin>>n)
    {
        priority_queue<int, vector<int>, greater<int> > q;
        ans = 0; // 清零
        while(n--)
        {
            cin>>i;
            q.push(i);
        }
        while(q.size() > 1)
        {
            int t1=q.top();
            q.pop();
            int t2=q.top();
            q.pop();
            ans += t1+t2;
            q.push(t1+t2);
        }
        //q.pop() // 清空队列
        cout<<ans<<endl; 
    }
    return 0;
}

Problem E:NEFU1692 堆

模板题。

#include<bits/stdc++.h>
using namespace std;
int n, m, num;
priority_queue<int, vector<int>, greater<int> > q;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    while(n--)
    {
        cin>>m;
        switch(m)
        {
            case 1:
                cin>>num;
                q.push(num);
                break;
            case 2:
                cout<<q.top()<<endl;
                break;
            default:
                q.pop();
                break;
        }
    }
    return 0;
}

Problem F:NEFU1691 瑞瑞的木板

同B题。注意数据范围。

#include<bits/stdc++.h>
using namespace std;
priority_queue<long long, vector<long long>, greater<long long> > q;
int main()
{
    ios::sync_with_stdio(false);
    long long n, i, ans=0;
    cin>>n;
    while(n--)
    {
        cin>>i;
        q.push(i);
    }
    while(q.size() > 1)
    {
        long long t1=q.top();
        q.pop();
        long long t2=q.top();
        q.pop();
        ans += t1+t2;
        q.push(t1+t2);
    }
    cout<<ans<<endl;
    return 0;
}

Problem G:NEFU1690 桐桐的新闻系统

dalao说用map做的啊,,我不会啊,,多定义一个值用来维护啊。。

#include<bits/stdc++.h>
using namespace std;
struct node{
    int Q_num, period, st; // st用来维护period的值
};
priority_queue<node, vector<node> > q;
bool operator<(const node &nod1, const node &nod2)
{
    if(nod1.period != nod2.period) return nod1.period > nod2.period;
    else return nod1.Q_num > nod2.Q_num;
}
int main()
{
    ios::sync_with_stdio(false);
    int k, num, per;
    string str;
    while(cin>>str)
    {
        if(str[0] == 'R')
        {
            cin>>num>>per;
            q.push({num, per, per});
        }
        if(str[0] == '#') break;
    }
    cin>>k;
    while(k--)
    {
        node tmp = q.top();
        q.pop();
        cout<<tmp.Q_num<<endl;
        tmp.period += tmp.st;
        q.push(tmp);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值