【CCF201909-4 推荐系统】

写在前面

本题考察的是对数据结构的建构,以及对STL的熟练运用。没有选择正确的数据结构,将会导致本题超时。

另外,此题的测试数据有误,在输出某一种类商品的编号时应当按照分数从高到低排序,分数相同时才按编号从小到大排序。如果按照原题意,只能得到60分。

我的思路(超时)

使用 unordered_map<id, score> map[type]; 存储物品

  • 在插入、删除时,只需要O(1)。因此初始化m*n件物品时消耗O(m*n),插入删除操作消耗O(op)。
  • 在查询时,我的做法是将m*n件物品从哈希表中取出,每个物品是 <type, id, score> = Commodity 三元组。以建堆的算法构建 priority_queue <Commodity>,耗时O(m*n)。随后从堆顶依次找到k个商品,耗时大概为O(k*log(m*n))。
  • 总用时为O(m * n + op + 100 * (m * n + k * log(m * n) ) ) = 1.5 * 108。加上操作复杂,实际应当达到了109的数量级,必超时。

网友思路1(满分)

https://blog.csdn.net/richenyunqi/article/details/101396817

使用 set<Commodity> 存储物品,其中 Commodity = <type, id, score> ,使用时定义顺序为score降序、type升序、id升序。

  • 对于查询操作,只需要顺序遍历set,找到符合条件的k个商品即可。时间复杂度O(K)。

  • 对于插入删除操作,需要根据typeid查找到相应的Commodity。这里网友用的一个骚操作是:用哈希表unordered_map<(type, id), set::iterator>存储set的迭代器!!!

    时间复杂度为O(log(m*n))。

  • 总用时为O(m * n * log(m * n) + op * log(m * n) + 100 * k) = 9 *10^7

网友思路2(满分)

https://blog.csdn.net/best335/article/details/101315966

  • 使用map<int,set<pair<int,int> > > F保存所有数据,格式为map<Score,set<pair<Type,Commodity> > >
    这样在容器内部首先会按Score排序,同一Score的先按Type排序,再按Commodity排序。
  • 使用unordered_map<int,int>[50]保存编号到成绩的映射,格式为unordered_map<Commodity,Score> G[Type]。这样指定Type和Commodity可以在F中迅速定位,从F中增删商品的时间度为O(log(Score的种数) * log(该分数的物品数))。

手动开启O2、O3优化

#pragma GCC optimize(2)

#pragma GCC optimize(3,"Ofast","inline")
发布了95 篇原创文章 · 获赞 148 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/104304929