思路
这题贼坑,题目的排序方式写的乱七八糟。
- 一开始个人理解里是每一个种类根据id从小到大的原则输出。也就是说:先所有商品根据score排序,再根据搜索命令得到k个score最大的商品,其中0…m类还要限制在k0 , k1,k2,k3,…,km-1的范围内。输出时候根据类从小到大,id从小到大的顺序输出。
- 但其实输出的时候根本无需对每个类中的id排序,只需要根据score从小到大的顺序输出即可,在score相同的情况下才考虑id。
- 针对需要排序并且常做插入和删除操作的情况,我们使用set,并使用map对该商品在set中的位置进行记录。注意set中node(树写习惯了不小心打成node了)的id并非单纯的商品id,而是type * comax+id,这样可以同时在set中保存type和id。
- 本题实则为set和map的合作考察以及各种sort的变种。反而没有图论麻烦,不太像是第四题的风格(笑)
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
//-1
struct node{
LL id=0;
LL score=0;
bool operator<(const node& c) const{
if(this->score==c.score )
return this->id<c.id;
return this->score>c.score;
}
};
int main(){
set<node> save;
map<LL, set<node>::iterator> pos;
int m=0,n=0;
cin>>m>>n;
const LL comax=1e9;
for(int j=0;j<n;j++){
int id=0;
int temp=0;
cin>>id>>temp;
for(int i=0;i<m;i++){
LL a=i*comax+id;
node nodet;
nodet.id=a;
nodet.score=temp;
pos[a]=save.insert(nodet).first;
}
}
int opn=0;
cin>>opn;
while(opn--){
int optemp=0;
cin>>optemp;
//cout<<optemp<<endl;
if(optemp==1){
int type=0,com=0,score=0;
cin>>type>>com>>score;
LL a=type*comax+com;
node nodet;
nodet.id=a;
nodet.score=score;
pos[a]=save.insert(nodet).first;
}
else if(optemp==2){
int type=0,com=0;
cin>>type>>com;
LL a=type*comax+com;
save.erase(pos[a]);
pos.erase(a);
}
else{
int count[55]={0};
int k=0;
cin>>k;
vector< vector <int> > ans(m);
for(int i=0;i<m;i++){
cin>>count[i];
}
set<node>::iterator iter=save.begin();
for(;iter!=save.end();iter++){
node i=*iter;
int realm=i.id/comax;
if(ans[realm].size()<count[realm]){
ans[realm].push_back(i.id%comax);
if(--k==0)
break;
}
}
for(int i=0;i<m;i++){
if(ans[i].empty())
cout<<"-1";
else{
for(int j=0;j<ans[i].size();j++){
cout<<ans[i][j]<<" ";
}
}
cout<<endl;
}
}
}
return 0;
}