ccf认证 201909-4

ccf认证 201909-4

主要思路是:

  1. 用优先级队列数组来储存每一个类别的商品,优先级队列的元素是自定义的结构体,里面有cls、id、score三个元素,并且根据题目的排序要求重载了 < 运算符
  2. 用一个map数组来存储关于商品删除的信息,以配合优先级队列进行实现隐式的删除操作
  3. 增加商品时,只要添加进入优先级队列即可
  4. 删除商品时,不对优先级队列进行操作,只设置相应的deleted状态位true,在查询操作时要跳过deleted为true的元素
  5. 查询时,建立一个总优先级队列PQ,将每个类中排名最高的元素放进优先级队列,之后进行循环,每次访问PQ的top,如果该类名额已经用完,则continue,否则将该类对应的优先级队列进行pop,以使得接下来的元素能够上来并加入PQ中。对于pop出来的元素,用ans向量记录,在输出时输出ans向量,并重新将元素push进去
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std;

struct node {
    int cls, id, score;
    friend bool operator<(const node &a, const node &b) {
        if (a.score != b.score)
            return a.score < b.score;
        return a.cls != b.cls ? a.cls > b.cls : a.id > b.id;
    }
    node() { }
    node(int _cls, int _id, int _sco): cls(_cls), id(_id), score(_sco) { }
};

bool cmp(const node &a, const node &b) {
    return a.id < b.id;
}

const int maxm = 52;
const int maxn = 30010;
priority_queue<node> all[maxm]; 
int n, m;
map<int, bool> deleted[maxm];

int main() {
    cin >> m >> n;
    for (int i = 0; i < n; i++) {
        int id, score;
        cin >> id >> score;
        for (int j = 1; j <= m; j++)
            all[j].push(node(j, id, score));
    }

    int op_num;
    cin >> op_num;
    for (int i = 0; i < op_num; i++) {
        int op;
        cin >> op;
        if (op == 1) {
            int type, id, sco;
            cin >> type >> id >> sco;
            type++;
            all[type].push(node(type, id, sco));
            deleted[type][id] = false;
        } else if (op == 2) {
            int type, id;
            cin >> type >> id;
            type++;
            deleted[type][id] = true;
        } else {
            int K;
            vector<int> k_i(m+1, 0);
            priority_queue<node> PQ;
            vector<node> ans[m+1];
            cin >> K;
            for (int j = 1; j <= m; j++) {
                cin >> k_i[j];
            }
            for (int j = 1; j <= m; j++) {
                while (!all[j].empty() && deleted[j][all[j].top().id])
                    all[j].pop();
                if (!all[j].empty())
                    PQ.push(all[j].top());
            }
            while (!PQ.empty() && K) {
                node tmp = PQ.top(); PQ.pop();
                if (k_i[tmp.cls] <= 0) {
                    continue;
                }
                K--;
                k_i[tmp.cls]--;
                ans[tmp.cls].push_back(tmp);
                all[tmp.cls].pop();
                while (!all[tmp.cls].empty() && deleted[tmp.cls][all[tmp.cls].top().id] == true) {
                    all[tmp.cls].pop();
                }
                if (!all[tmp.cls].empty()) {
                    PQ.push(all[tmp.cls].top());
                }
            }
            for (int j = 1; j <= m; j++) {
                //sort(ans[j].begin(), ans[j].end(), cmp);  //按题目是要排序的,但排序了只有60分,不排序提交100分
                for (auto &e : ans[j]) {
                    cout << e.id << " ";
                    all[e.cls].push(e);
                }
                if (ans[j].empty())
                    cout << -1;
                cout << endl;
            }
        }
    }
    return 0;
}


/*
2 3
1 3
2 2
3 1
8
3 100 1 1
1 0 4 3
1 0 5 1
3 10 2 2
3 10 1 1
2 0 1
3 2 1 1
3 1 1 1
*/
原创文章 8 获赞 16 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Governor2601/article/details/101475266