1. 程式人生 > 實用技巧 >模擬題-推薦系統

模擬題-推薦系統

題目大意:

思路:

  這個題目要用到資料結構+離散化,首先想一下如何存每一類的id和分數,更容易找到指定類別和id的物品移除,因為set是有序的所以我們可以維護一個set來儲存當前時間點的所有物品,按照負的分數從小到大排列,如果遇到第三種操作就遍歷當前的商品,順便判斷當前類別商品的個數是否達到上限並且總選擇商品數是否達到上限,此處因為類別數比較小,所以採用離散化來做,具體來說就是第c類的第id個物品會變成 c*maxid+id,由於maxid最大為1e9所以要用到long long+map來存分數的對映,具體見程式碼

程式碼:

#include <iostream>
#include 
<queue> #include <unordered_map> #include <set> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll MAXID=1e9+10; unordered_map<ll,int> id_to_sc; set<pll> goods; int main(){ int m,n; cin>>m>>n; for(int i=0;i<n;i++){
int id,score; cin>>id>>score; for(int j=0;j<m;j++){ ll nid=j*MAXID+id; goods.insert({-score,nid}); id_to_sc[nid]=score; } } int ops; cin>>ops; for(int i=0;i<ops;i++){ int p; cin>>p;
if(p==1){ int c,id,sc; cin>>c>>id>>sc; ll nid=c*MAXID+id; goods.insert({-sc,nid}); id_to_sc[nid]=sc; } else if(p==2){ int c,id; cin>>c>>id; ll nid=c*MAXID+id; int sc=id_to_sc[nid]; goods.erase({-sc,nid}); id_to_sc.erase(nid); } else if(p==3){ int up[55]; vector<int> res[55]; int k; cin>>k; for(int j=0;j<m;j++)cin>>up[j]; for(auto& good:goods){ int c=good.second/MAXID; int id=good.second%MAXID; if(up[c]>0){ res[c].push_back(id); up[c]--; if(--k==0)break; } } for(int j=0;j<m;j++){ if(!res[j].size())puts("-1"); else { for(int k=0;k<res[j].size();k++){ cout<<res[j][k]<<" "; } cout<<endl; } } } } }