题解思路:
先说一下解题思路吧,这是一道比较明晰的模拟题,由m种物品,每一种物品都会被打分,题目要求你筛选出k个打分靠前的物品,并且这些物品的种类每一个都必须要有阈值,也就是说这个类型的不能存入超过这个阈值的数量.
那么这一题是一个模拟题,首先梳理题意的时候就必须注意到,这是一道对所有物品得分进行排序,然后对于同分的物品又要对序号进行升序排序,直接可以想zhe到struct + set的算法,值得提一下的两点: 1. set算法insert过后会返回一个pair<set<T>::iterator,bool>,第一个参数返回的是在set中的位置迭代器,第二个则表示插入的成功与否. 2.如果要让struct能够在set中排序 需要重载操作符
bool operator<(const node& rhs)const{} const十分重要! STL没学好的小伙伴可以看看C++标准库 会有很大的收获!
那么这一题 我们其实只要定义一个 set<Node> S;类型的集合就可,然后 按照题意重载操作符并插入到集合中,取出的时候要注意阈值问题,用vector<vector<int> > ans来存储答案, 我借鉴了网上一个比较巧妙的写法 if(ans[type].size() < kseq[type]) ...//insert operation . 详细写法见下方代码....值得提一下的是 这里行标表示的是物品类型.
废话不多说 直接上AC代码!
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m,n;
struct node{
ll id;
ll score;
bool operator<(const node& rhs)const{
if(score == rhs.score)
return id < rhs.id;
return score > rhs.score;
}
node(ll id = 0,ll score = 0):
id(id),score(score){}
};
set<node> nodeSeq;
const ll mod = 1e9;
unordered_map<ll,set<node>::iterator> mp;
void addToQueue(){
ll type,id,score;
cin >> type >> id >> score;
mp[type*mod + id] = nodeSeq.insert(node(type*mod+ id,score)).first;
}
map<ll,bool> vis;
void dropEle(){
ll type,id;
cin >> type >> id;
vis[type*mod + id] = true;
mp.erase(type*mod+id);
}
void queryData(){
int k;
cin >> k;
int s = 0;
vector<int> kseq(m);
vector<vector<ll> > ans;
ans.resize(m);
for(int i = 0 ; i < m ; ++i){
cin >> kseq[i];
s += kseq[i];
}
for(auto it : nodeSeq){
if(vis[it.id] == true) continue;
ll type = it.id/mod;
if(ans[type].size() < kseq[type]){
ans[type].push_back(it.id%mod);
}
k--;
if(k == 0) break;
}
for(auto it : ans){
if(it.empty()){
cout << -1 << endl;
}else{
for(auto j:it){
cout << j << " ";
}
cout << endl;
}
}
}
int main(){
cin >> m >> n;
for(ll i = 0 ; i < n ;++i){
ll id,score;
cin >> id >> score;
for(ll type = 0 ; type < m ; ++type){
nodeSeq.insert(node(type*1e9 + id,score));
}
}
int op;
cin >> op;
for(int i = 0 ; i < op ; i++){
int type;
cin >> type;
if(type == 1){
addToQueue();
}else if(type == 2){
dropEle();
}else if(type == 3){
queryData();
}
}
return 0;
}
本题反思:
这题我换了很多的写法,一开始使用都是priority_queue<node> 优先队列的写法,首先发现用当下的node重载规则去排序必须反过来去写,结果只拿了十分,结果发现我读错题意了,以至于我后面的vector<vector<>>模拟的写法都没有通过.
所以读题很重要啊
另外 我个人感觉这题和pat甲级的table tennis一样属于比较恶心的STL题 吐了