记录一个菜逼的成长。。
题目大意:
给你n个数和k大小的空间。
在每次访问第i个数之前,先输出第i个数之前k个按出现次数从大到小排列后的数,如果次数相同则按数的大小从小到大输出。
用一个优先队列来维护,每次输出前k个。
几个数组:
vis[i] := 表示i是否在前k个输出的数里
use[i] := 表示i是否之前出现过。
对于每一个访问的数(除了第一个),先输出前k个,不满k个则全输出。保存在一个中间数组里。
之后再对访问的数进行计数,如果之前没访问过的放进优先队列
如果之前访问过了,但是没在输出的数了,对优先队列进行出队操作,直到这个数出队。
然后再将中间数组里的数放进优先队列。
原来想把代码写好看点。。然而总有点过不了,最后直接暴力了一发。。
代码略丑。。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50000 + 10;
int cnt[maxn],vis[maxn],use[maxn];
struct cmp{
bool operator()(const int &a,const int &b)const{
if(cnt[a] != cnt[b])return cnt[a] < cnt[b];
return a > b;
}
};
priority_queue<int,vector<int>,cmp>q;
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k)){
vector<int>tmp;
for( int i = 0,x; i < n; i++ ){
scanf("%d",&x);
int c = 0;
if(i){
printf("%d:",x);
while(c < k && !q.empty()){
int t = q.top();
vis[t] = 1;
tmp.push_back(t);
printf(" %d",t);
q.pop();c++;
}
puts("");
}
cnt[x]++;
if(!use[x]){
use[x] = 1;
q.push(x);
}
else {
if(!vis[x]){
while(q.top() != x){
tmp.push_back(q.top());q.pop();
}
tmp.push_back(q.top());q.pop();
}
}
for( int i = 0; i < tmp.size(); i++ )
q.push(tmp[i]),vis[tmp[i]] = 0;
tmp.clear();
}
}
return 0;
}