#OJ285. 序列M小和 + set(STL)大顶堆的应用 + pair的用法

OJ题目链接https://oj.haizeix.com/problem/285

如果要变成大顶堆,有一个小技巧就是只需要在插入的时候,对元素取相反的极性就可以了,拿出来用的时候再还原回去。

题解代码:

#include<iostream>
#include<set>
using namespace std;

#define inf 0x3f3f3f3f
#define MAX_M 2000

int a[MAX_M + 5];
typedef pair<int, int> PII; // <set>头文件自动引入pair
set<PII> s;
int t = 0; // 时间戳,去重
int n, m, x;

void extract() {
    for (int j = m - 1; j >= 0; j--) {
        a[j] = -(s.begin()->first);
        s.erase(s.begin());
    }   
}
int main() {
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> x;
        s.insert(PII(-x, t++));
    }
    for (int i = 1; i < n; i++) {
        extract(); // 这个是第一层的所有元素跟第二层的所有元素配对完以后剩下的大顶堆中的元素作为一二两层元素的代表前往第三层匹配。以此类推,不断合并。
        for (int i = 0; i < m; i++) s.insert(PII(-inf, t++)); // set内部维护有序性的时候是依据pair中的first元素来的
        for (int j = 0; j < m; j++) { 
            cin >> x;
            for (int k = 0; k < m; k++) {
                int y = x + a[k];
                if (y >= -(s.begin()->first)) break;
                s.erase(s.begin());
                s.insert(PII(-y, t++)); 
            }
        }
    }
    extract();
    for (int i = 0; i < m; i++) {
        i && cout << " ";
        cout << a[i];
    }
    cout << endl;
    return 0;
}
posted @ 2023-05-03 17:57  江韵阁  阅读(69)  评论(0)    收藏  举报