CCF CSP 201909-4 推荐系统

思路:

1.将所有商品存进set里,按分数降序排序,如果分数相同,判断它们是否为同类商品,如果是,则按编号升序排序,如果不是,则按类别编号升序排序;
2.增加删除什么的直接在set里操作就行了;
3.查询时,用m个vector存储需要输出的商品,然后从前往后扫set,如果该商品对应的类别没有满,则将它加入对应的vector,如果总数量等于k,则退出查找;
4.最后将m个vector挨个输出就好啦;
PS:不要按题意“同类商品的编号从小到大输出”,这样只有60分,不排序直接输出就能AC了~

代码:

#define IOS ios::sync_with_stdio(false);cin.tie(0)
#include<bits/stdc++.h>
using namespace std;
#define mem(a,x) memset(a,x,sizeof(a))
#define pb(a) push_back(a)
#define rp(i,n) for(int i=0;i<n;i++)
#define rpn(i,n) for(int i=1;i<=n;i++)
struct goods{
	int type,no,score;
	goods(int t=0,int n=0,int s=0):type(t),no(n),score(s){}
	bool operator<(const goods& a)const{
		if(score==a.score){
			return type==a.type?no<a.no:type<a.type;
		}else return score>a.score;
	}
};
const int MAX_M=55;
unordered_map<int,int> sc[MAX_M];
int ans[MAX_M];//各类商品已选取数量
int scale[MAX_M];//各类商品最多选取数量
vector<int> v[MAX_M];//输出 
set<goods> st;
int main(){
	IOS;
	int m,n;
	cin>>m>>n;
	rp(i,n){//所有0~m-1类商品的第i个商品 
		int id,s;
		cin>>id>>s;
		rp(j,m){
			st.insert(goods(j,id,s));
			sc[j][id]=s;
		}
	}
	int op;
	cin>>op;
	rp(i,op){
		int no;
		cin>>no;
		if(no==1){
			int type,no,s;
			cin>>type>>no>>s;
			st.insert(goods(type,no,s));
			sc[type][no]=s;
		}else if(no==2){
			int type,no;
			cin>>type>>no;
			st.erase(goods(type,no,sc[type][no]));
		}else{
			int k;
			cin>>k;
			mem(ans,0),mem(scale,0);
			rp(j,m) cin>>scale[j];
			int total=0;
			for(auto e:st){
				if(ans[e.type]<scale[e.type]){
					v[e.type].pb(e.no);
					ans[e.type]++,total++;
					if(total>=k) break;
				}
			}
			rp(j,m){
				if(v[j].size()){
				//	sort(v[j].begin(),v[j].end());
					cout<<v[j][0];
					for(int pos=1;pos<v[j].size();pos++) cout<<' '<<v[j][pos];
					cout<<'
';
					v[j].clear();
				}else cout<<"-1
";
			}
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/yuhan-blog/p/12308889.html