CCF 201909-4 推荐系统 超时&&100分

本题梳理:
共有m类产品:0~m-1类;
“对于每个app新用户,每类商品初始有编号不同的n个商品”:这句话的意思是说开始输入时各类产品有n个相同的产品,这个相同包括产品编号和评分都相同。
然后可以进行操作:插入/删除/查询
插入:指明类别和编号和评分
删除:指明类别和编号
查询:从所有的产品中查询评分前k个产品,且是尽量查询(即能找到多少是多少最多不过k个)
而且每一类产品也有个数限制且也有个数限制。
原则是:(1)若两个评分相同且在同一类中,则选择编号小的。(2)若两个评分相同且不在同一类中,则选择类号小的

首先是超时代码,得了10分:

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
struct Good{
    
    
    int  type;
    int  commodity;
    int  score;
};
class compare{
    
    
public:
    bool operator()(const Good g1,const Good g2)
    {
    
    
        if(g1.score == g2.score&&g1.type == g2.type)
        {
    
    
            return g1.commodity<g2.commodity;
        }else if(g1.score == g2.score&&g1.type != g2.type)
        {
    
    
            return g1.type<g2.type;
        }else
            return g1.score > g2.score;
    }
};
Good good;
int n,m,commodity,score;
set<Good,compare> goods;
set<Good,compare>::iterator it;
vector<int> chose_good[52];//存储各类已选商品的编号
int cns[52];//记录各类已选商品的个数
void my_print(Good good)
{
    
    
    cout<<good.type<<" "<<good.commodity<<" "<<good.score<<endl;
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    int i,j,opnum,op,threshold,type_threshold[52],type,commodity;
    cin>>m>>n;
    for(i=0;i<n;i++)
    {
    
    
        cin>>commodity>>score;
        good.commodity=commodity;
        good.score    = score;
        for(j=0;j<m;j++)
        {
    
    
            good.type=j;
            goods.insert(good);
        }
    }
    cin>>opnum;
    for(i=0;i<opnum;i++)
    {
    
    
        cin>>op;
        switch(op){
    
    
        case 1:
            cin>>good.type>>good.commodity>>good.score;
            goods.insert(good);
            cout<<"添加后:"<<endl;
            for_each(goods.begin(),goods.end(),my_print);
            break;
        case 2:
            cin>>type>>commodity;
            for(it=goods.begin();it!=goods.end();it++)
            {
    
    
                if(it->type == type&&it->commodity == commodity) break;
            }
            if(it!=goods.end())
                goods.erase(it);
            cout<<"删除后:"<<endl;
            for_each(goods.begin(),goods.end(),my_print);
            break;
        case 3:
            for(j=0;j<52;j++)
            {
    
    
                cns[j]=0;
                chose_good[j].clear();
            }//cns[51]代表已选总数。
            cin>>threshold;
            for(j=0;j<m;j++)
            {
    
    
                cin>>type_threshold[j];//各类别的限制
            }
            for(it=goods.begin();cns[51]<threshold&&it!=goods.end();it++)
            {
    
    
                if(cns[it->type] < type_threshold[it->type])
                {
    
    
                    chose_good[it->type].push_back(it->commodity);
                    cns[51]++;
                    cns[it->type]++;
                }
            }
            for(j=0;j<m;j++)
            {
    
    
                if(chose_good[j].size()==0)
                {
    
    
                    cout<<"-1"<<endl;
                    continue;
                }
                for(vector<int>::iterator it=chose_good[j].begin();it!=chose_good[j].end();it++)
                {
    
    
                     if(it==chose_good[j].begin())
                        cout<<*it;
                    else
                        cout<<" "<<*it;
                }
                cout<<endl;
            }
            break;
        }
    }
    return 0;
}

然后是100分代码,参考了某位大佬的“惰性删除”思想,虽然不知道是哪里的思想,但是不超时了。也没怎么弄懂是怎么节省时间的(后来不也经历了先查询后删除吗)。

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
struct Good{
    
    
    int  type;
    int  commodity;
    int  score;
};

struct Del{
    
    
	int type;
	int id;

	Del(int _type, int _id){
    
    
		type=_type; id=_id;
	}

	bool operator < (const Del &rhs) const{
    
    
		if(type==rhs.type) return id<rhs.id;
		return type<rhs.type;
	}
};

class compare{
    
    
public:
    bool operator()(const Good g1,const Good g2)
    {
    
    
        if(g1.score == g2.score&&g1.type == g2.type)
        {
    
    
            return g1.commodity<g2.commodity;
        }else if(g1.score == g2.score&&g1.type != g2.type)
        {
    
    
            return g1.type<g2.type;
        }else
            return g1.score > g2.score;
    }
};
Good good;
int n,m,commodity,score;
set<Good,compare> goods;
set<Del> has_del;
set<Good,compare>::iterator it;
vector<int> chose_good[52];//存储各类已选商品的编号
int cns[52];//记录各类已选商品的个数
void my_print(Good good)
{
    
    
    cout<<good.type<<" "<<good.commodity<<" "<<good.score<<endl;
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    int i,j,opnum,op,threshold,type_threshold[52],type,commodity;
    cin>>m>>n;
    for(i=0;i<n;i++)
    {
    
    
        cin>>commodity>>score;
        good.commodity=commodity;
        good.score    = score;
        for(j=0;j<m;j++)
        {
    
    
            good.type=j;
            goods.insert(good);
        }
    }
    cin>>opnum;
    for(i=0;i<opnum;i++)
    {
    
    
        cin>>op;
        switch(op){
    
    
        case 1:
            cin>>good.type>>good.commodity>>good.score;
            goods.insert(good);
            break;
        case 2:
            cin>>type>>commodity;
            has_del.insert(Del(type, commodity)); //将该商品加入删除表中,实行惰性删除
            break;
        case 3:
            for(j=0;j<52;j++)
            {
    
    
                cns[j]=0;
                chose_good[j].clear();
            }//cns[51]代表已选总数。
            cin>>threshold;
            for(j=0;j<m;j++)
            {
    
    
                cin>>type_threshold[j];//各类别的限制
            }
            for(it=goods.begin(); cns[51]<threshold && it!=goods.end();){
    
    
				//该类商品未选满,查看该商品是否已删除
				if(cns[(*it).type]<type_threshold[(*it).type]){
    
    
					if(has_del.find(Del((*it).type, (*it).commodity))!=has_del.end()){
    
     //存在于删除表中
						goods.erase(it++); //删除该元素,迭代器自增
					}
					//未删除
					else{
    
    
						++cns[(*it).type];
						++cns[51];
						chose_good[(*it).type].push_back((*it).commodity);
						it++;
					}
				}
				else it++;
			}
            for(j=0;j<m;j++)
            {
    
    
                if(chose_good[j].size()==0)
                {
    
    
                    cout<<"-1"<<endl;
                    continue;
                }
                for(vector<int>::iterator it=chose_good[j].begin();it!=chose_good[j].end();it++)
                {
    
    
                     if(it==chose_good[j].begin())
                        cout<<*it;
                    else
                        cout<<" "<<*it;
                }
                cout<<endl;
            }
            break;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44142774/article/details/113481448