201909-4 CSP认证 推荐系统(set + map容器)

题目思路:

       首先要告诉读者的是,在set和map中,内部结构为平衡二叉树,所以insert和erase并不会改变容器中其他元素的迭代器,但是vector会,它属于连续存储,所以他的push_abck和erase,insert函数都会改变其他元素的在内存中的位置。

具体做法:

       使用一个set数组记录每一类型商品中的元素,由一个三元组构成(类型,编号,评分),那么,插入的话就可以往对应的set中插入三元组。那么怎么处理删除呢,set的erase有两种参数,一种是删除迭代器,一种是删除数值,那么我们要么记录迭代器,要么记录数值,很显然这里需要一个map

      做法1:我们把(类型,编号)作为键,评分一直在变,所以作为值,在插入和初始化的时候就更新了map

      做法2:我们把(类型,编号)作为键,迭代器作为值,这个怎么搞就成问题了,有一个冷门知识就是,set的insert函数其实是有返回值的,是一个pair,first就是迭代器,second是bool类型,表示插入是否成功。

       在操作3查询的时候,我们直接遍历,每个类型的set,注意到编号可以很多,但是K只有100 , 所以对于一个集合,只取min(K,Max[i])个,那么50个set的话最多取5000个,只要在这5000个里边,排个序,取前K个,输出就行。

     排序的话,第一优先级是评分,从大到小,第二优先级是类型,从小到大,第三优先级是编号,从小到大。

可是!!!!!!

      会发现只有60分,说超时了,第一想法是改成C语言的输入,或者关掉同步流。提交!70分,运行超时。

这个时候我们来计算一下时间复杂度,对于插入和删除的复杂读是O(nlogn)的完全没问题,查询的复杂度,

   O(m*k*log n),理论上一点问题都没有,最多多个常数,也不会导致超时,何况题目5s。

但是就是超时了,这个情况让我想起了2019的秦皇岛A题,就是卡时间,原因也是我使用map拿pair做键值,最后是把pair改成哈希使用unordered-map过的,只不过键值必须是整形,所以要哈希一下。这个题同样,把键值pair哈希掉就可以了。改用unorderde-map。查询速度接近O(1).

#include
#define ll long long
using namespace std;
const int MAXN = 1e5+5;
struct node
{
    int tp,id,sc;
    node(){}
    node(int a,int b,int c){
        tp = a;id = b;sc = c;
    }
    bool operator <(const node r)const{
        if(sc == r.sc){
            if(tp == r.tp){
                return idr.sc;
    }
};
ll Hash(ll a,ll b)
{
    ll ret = 0;
    return (ll)a*(ll)1e10 + b;
}
unordered_mapmp;
setst[55];
int m,n;
int main()
{
    mp.clear();
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++){
        int id,sc;
        scanf("%d%d",&id,&sc);
        for(int j=0;jv[55];
            vectorss;
            ss.clear();
            int k;
            scanf("%d",&k);
            for(int i=0;i::iterator it;
                for(it = st[i].begin();it!=st[i].end();it++){
                    cnt++;
                    if(cnt>k ||cnt > Max[i])break;
                    ss.push_back((*it));
                }
            }
            int cnt = 0;
            sort(ss.begin(),ss.end());
            int len = ss.size();
            for(int j=0;j k)break;
                int tp = ss[j].tp;
                int id = ss[j].id;
                int sc = ss[j].sc;
                v[tp].push_back(id);
            }
            for(int i=0;i

 

你可能感兴趣的:(201909-4 CSP认证 推荐系统(set + map容器))