对于这道题目,首先我们需要记录某个商品出现的次数,这里我选择用一个map来进行记录;然后我们还需要一个数组来维护访问频率排在前k的商品。
如何维护这前k件商品呢:如果当前正在访问的商品不再前k个里面,那么直接把它加入数组,然后把商品按频次降序排序,如果加入该商品之后使得商品数目达到k+1了,那么还需要去掉最后一个商品。
利用STL的实现
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
unordered_map<int,int> maps;
// typedef pair<int,int> PII;
struct PII{
int idx;
int times;
bool operator<(PII &p1)const{
if(times!=p1.times) return times>p1.times;
return idx<p1.idx;
}
};
int main(){
int n,k;
cin>>n>>k;
vector<PII> v;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(i!=1){
printf("%d:",x);
for(auto t:v) printf(" %d",t.idx);
puts("");
}
maps[x]++;
bool exist=false;//注意可能x已经在前k个里面了,注意判重
for(int i=0;i<v.size();i++){
if(v[i].idx==x){
exist=true;
v[i].times=maps[x];
break;
}
}
if(!exist)
v.push_back({x,maps[x]});
sort(v.begin(),v.end());
if(v.size()>k) v.pop_back();
}
return 0;
}
学习下y总的写法
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 50010;
int n, m;
int cnt[N];
int top_k[11];
int main()
{
scanf("%d%d", &n, &m);
int k = 0;
for (int i = 0; i < n; i ++ )
{
int id;
scanf("%d", &id);
if (i)
{
printf("%d:", id);
for (int j = 0; j < k; j ++ ) printf(" %d", top_k[j]);
puts("");
}
cnt[id] ++ ;
bool exists = false;
for (int j = 0; j < k; j ++ )
if (top_k[j] == id)
{
exists = true;
break;
}
if (!exists) top_k[k ++ ] = id;
sort(top_k, top_k + k, [](int x, int y){
if (cnt[x] != cnt[y]) return cnt[x] > cnt[y];
return x < y;
});
k = min(k, m);
}
return 0;
}