#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<map>
using namespace std;
//70min
//耗时于修改bug
/*************************
题意:每当购买1个商品序号时,推荐k个商品,推荐要求为:
之前购买商品数量最大
若数量相等,选择序号最小的。
*************************/
/************************
求解要点:输出前k个,考虑用优先队列维持该推荐序列
每次购买商品后,按优先队列顺序输出商品,并存入一个栈中。
推荐之后,要更新队列
★关键:只需要检查最后一个出队的商品
若数量比当前商品小,肯定要被剔除
若数量相等,序号比它小,肯定也要被剔除。
故将这个商品拿出栈,存入当前商品
最后将栈中的商品重新倒回优先队列中
时间复杂度O(n*k)
************************/
/***********************
笔记:
写优先队列的判断准则时,
一定不要遗漏return false!
*********************/
#define INF 0xfffffff //int32位,去除首位符号位,最大为该值
#define M 60000
int n,m;
struct item{
int id;
int num;
bool operator < (const struct item &a) const
{
//<出最大的
if(num<a.num)
return true;
else if(num==a.num)
{
return id>a.id; //输出id小的
}
else return false;
}
};
int Count[M];
int main()
{
int i,j;
int m,n,c;
int id,k;
memset(Count,0,sizeof(Count));
priority_queue<struct item> q;
scanf("%d%d",&n,&k);
struct item t;
stack<item> sta;
int cmin;
t.num=-1;
int flag;
for(i=0;i<n;i++)
{
scanf("%d",&id);
Count[id]++;
if(i!=0)
printf("%d:",id);
flag=1;
for(j=0;j<k&&(!q.empty());j++)
{
t=q.top();
printf(" %d",t.id);
if(t.id == id)
{
t.num=Count[id];
flag=0; //无需更新
}
sta.push(t);
q.pop();
}
if(i!=0)
cout<<endl;
if(flag==1)
{
cmin=t.num;
//如果第k个的值(双条件)比当前小,则最后一个肯定被剔除,把当前插入前k队列
if(j==k )
{
if(Count[id]>t.num || (Count[id]==t.num && id < t.id))
{
sta.pop(); //去掉最后一个
t.id=id; //把当前这个放进去
t.num=Count[id];
sta.push(t);
}
}
else if(j<k)
{
t.id=id;
t.num=Count[id];
sta.push(t);
}
}
while(!sta.empty())
{
t=sta.top();
q.push(t);
sta.pop();
}
}
return 0;
}
PAT 1129. Recommendation System (25) 优先队列--维持前k个最大堆
最新推荐文章于 2020-08-03 17:36:01 发布