[CSP17 201909-4题解]推荐系统 TLE

  • 意料之外的是一道简单模拟,只需要按照题意进行增删查即可。维护一个set,查询时需要注意好关于三个关键字的排序输出,score -> type ->id的先后次序进行大小排序。题目给了5s的时间,我按照简单的模拟思路写,不清楚会不会超时,但是按照题目给的时间,感觉应该不会需要特别好的复杂度优化。
  • 以下代码仅通过部分样例,能否AC未知。仅供各位参考,共同学习进步
  • 2019年9月24日补充:今天CCF官网的题库增加了CSP17的题,提交后超时,仅过了一个测试点。有兴趣的朋友可以尝试一下继续优化,或者换个思路。
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

struct sp{
	int type;						// 记录商品类型 方便后续排序 
	int id;							// 记录商品id 
	int score;						// 记录商品热度 
};
struct cmp													// set排序重写 
{
	bool operator()(const sp &r1, const sp &r2)
	{
		if(r1.score != r2.score)return r1.score > r2.score;	//优先比较热度,大的优先 
		if(r1.type != r2.type)return r1.type < r2.type;		//其次比较类型,小的优先 
		return r1.id < r2.id;								//最后比较id,小的优先 
	}
};

set<sp,cmp> S;											// 保存各类商品详情 
vector<int> C[100005];									// 保存操作命令; 
int m, n, op;

void outList()											// 用于输出当前的商品情况(调试用的) 
{
	cout << "search:"<<endl;
	for(set<sp,cmp>::iterator it = S.begin(); it != S.end(); it++)
	{
		cout << it->type << " " << it->id << " " << it->score << endl;
	}
}

void fun()
{
	for(int i = 0; i < op; i++)
	{
		int type = C[i][0];
		
		// 处理增加事件 
		if(type == 1)
		{
			int classfiy = C[i][1];
			sp tmp;
			tmp.type = classfiy;
			tmp.id = C[i][2];
			tmp.score = C[i][3];
			S.insert(tmp);
		}
		
		// 处理删除事件
		if(type == 2)
		{
			int classfiy = C[i][1];
			int id = C[i][2];
			for(set<sp,cmp>::iterator it = S.begin(); it != S.end(); it++)
			{
				if(it->id == id && it->type == classfiy)
				{
					S.erase(it);
				}
			}
		}
		
		// 处理查询事件 
		if(type == 3)
		{
			int Max = C[i][1];									// 存放当前输出命令允许的最大值 
			//outList();
			int max = 0;
			vector<sp> tmp_S[52]; 								// 记录当前需要输出的商品 
			for(set<sp,cmp>::iterator it = S.begin(); it != S.end(); it++)
			{
				if(max >= Max) break;							// 已经输出了足够的商品数量,不再进行输出
				sp tmp = *it;
				if(tmp_S[tmp.type].size() < C[i][2+tmp.type])	// 是当前类的商品 并且 当前类商品并没有完全足够
				{
					max++;
					tmp_S[tmp.type].push_back(tmp);
				}
			}
			for(int j = 0; j < m; j++)							// 输出商品 
			{
				if(tmp_S[j].size() == 0)
				{
					cout << "-1\n";
				}
				else
				{
					for(int z = 0; z < tmp_S[j].size(); z++)
					{
						cout <<tmp_S[j][z].id << " ";
					}
					cout << endl;
				}
			}
		}
	}
} 

int main()
{
	cin >> m >> n;
	for(int i = 0; i < n; i++)
	{
		sp a;
		cin >> a.id >> a.score ;
		for(int j = 0; j < m; j++)						// 添加时,需要给每个类型的商品都添加同一个商品的id 
		{
			a.type = j;
			S.insert(a);
		}
	}
	cin >> op;
	for(int i = 0; i < op; i++)
	{
		int type;
		cin >> type;
		C[i].push_back(type);							// 按照不同命令类型进行分别的命令接收 
		if(type == 1)
		{
			int value;
			for(int j = 0; j < 3; j++)
			{
				cin >> value;
				C[i].push_back(value);
			}
		}
		if(type == 2)
		{
			int value;
			for(int j = 0; j < 2; j++)
			{
				cin >> value;
				C[i].push_back(value);
			}		
		}
		if(type == 3)
		{
			int value;
			for(int j = 0; j <=m; j++)
			{
				cin >> value;
				C[i].push_back(value);
			}
		}
	}
	fun();
	return 0;
}










评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值