題解思路:
先說一下解題思路吧,這是一道比較明晰的模擬題,由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題 吐了