201909-4 csp推荐系统

csp 201990 -4 推荐系统

题目描述

201909-4 csp推荐系统_第1张图片
201909-4 csp推荐系统_第2张图片

解题思路

这道题其实就是简单的模拟题,难点在于如何设计表,如何提高效率。如果单纯使用vector在数据量比较大的情况下会出现超时。我在做题的时候考虑过使用vector来解题,会出现超时的情况,因为插入和删除操作会导致vector内位置移动,会有大量操作。这一题可以使用set来解题,首先set的底层实际上是 一个红黑树,即平衡二叉树,这样插入的效率基本上保持在logN。set是自动有序的,那么对于查找操作也很方便,其效率基本保持在N。实际上比较耗时的是删除操作。我本来的想法是遍历整张表,根据type 和id 找到要删除的点之后再进行删除操作,但是这样操作的效率为N,如果我再维持一张表,根据提供的type和id ,我能够得到完整的商品信息,完整的商品信息对于set表来说是key,根据这个key再去表中查找删除,其中查找的效率仅为logN,相对来说速度有所提升。

  • 我本来以为对于删除操作,直接使用遍历时可以的,并不是非常耗时,但是我这样做会产生超时的问题,代码的分数时10分。于是我就牺牲空间换时间,使用更快的方法。这样才是满分。虽然我以为时间上似乎并没有差距很大。当然还可以不从set表中删除这个节点,直接标记map表,标记删除,在实际查询时掠过这些被标记删除的数据即可。
  • 这道题在官方测评上好像是有问题的,如果把最终结果按照题目意思排序,只有60分。如果不排序就是满分。我认为这是bug…
  • 下面的是满分代码,没有进行排序,如果排序的话可以使用set存储最终结果而不使用vector 或者存储完了之后排序。
#include
#include 
#include 
#include  
#include 
#include 
#include  
 
using namespace std;
class GOOD {
     
	public:int type;
	public:int id;
	public:int score;
	public:GOOD(){
     
		type = -1;
		id = -1;
		score = -1;
	}
	public:GOOD(int _type,int _id, int _score) {
     
		type = _type;
		id = _id;
		score = _score;
	}
	bool operator < (const GOOD d) const {
     
		return score > d.score || (score == d.score && type < d.type) || (score == d.score && type == d.type && id < d.id);
	}

};

struct INDEX {
     
	int type , id;
	INDEX(int _type , int _id):type(_type) , id(_id){
     }
	bool operator < (const INDEX d) const {
     
		return type < d.type || (type == d.type && id < d.id);
	}
};

int main() {
     
	int m, n;
	scanf("%d%d",&m,&n);
	set<GOOD> dataMap;
	map<INDEX , int> delMap;
	for (int i=0; i<n; i++) {
     
		int id, score;
		scanf("%d%d",&id,&score);
		for (int j=0;j<m;j++) {
     
			dataMap.insert(GOOD(j,id,score));
			delMap[INDEX(j,id)]= score;	
		}
	}
	int opnum ;
	scanf("%d",&opnum);
	while(opnum--) {
     
		int op;
		scanf("%d",&op);
		if (op == 1) {
      //add
			int type, commodity, sc;
			scanf("%d%d%d",&type,&commodity,&sc);
			dataMap.insert(GOOD(type,commodity,sc));
			delMap[INDEX(type,commodity)]= sc;	
		}else if (op == 2) {
      // delete 删除操作费时 
			int type, commodity;
			scanf("%d%d",&type,&commodity); // 迭代查询删除
			set<GOOD>::iterator it = dataMap.find(GOOD(type,commodity,delMap[INDEX(type,commodity)]));
			dataMap.erase(it);
			delMap[INDEX(type,commodity)] = -1;
		}else if (op == 3) {
      // query
			int sumNumber;
			int limit[100]={
     0};
			vector<int> res[100];
			scanf("%d",&sumNumber);
			for (int k=0; k<m;k++){
     
				scanf("%d",&limit[k]);
			}
			for (set<GOOD>::iterator it = dataMap.begin(); it!=dataMap.end()&&sumNumber;it++) {
     
				GOOD good = *it;
				if (limit[good.type]>0) {
     
					res[good.type].push_back(good.id);
					sumNumber--;
					limit[good.type]--;
				}
			}
			for (int p=0; p<m;p++) {
     
				if (res[p].size() == 0) {
     
					cout << "-1" ;
				}else {
     
					for (int h=0; h<res[p].size(); h++ ){
     
						if (h>0) {
     
							cout <<" ";
						}
						cout << res[p][h] ;						
					}
				}
				cout << endl;
			} 
		}
	}
	return 0;
}

Tips

想要做csp的模拟题,到官网上点模拟考试就好啦。关于set , vector ,map的不同,大家要去其他文章仔细研究一下比较好。

网址链接

你可能感兴趣的:(cps)