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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章