题目大意:给定口袋大小m,及一个大小为n的礼品序列,当新礼品加入时,如果相同礼品在口袋中,则该礼品的“平凡程度”+1,如果无相同礼品且有多余空间,则放入,如果无多余空间,则把平凡程度最大的礼物舍弃。若有相同,优先舍弃最早放入口袋中的礼品。求丢了多少次礼品
解析:优先队列处理 注意一些细节
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 1000005;
#define inf 0x3f3f3f3f
#define maxn 2000100
const int N = 10010;
struct node
{
int x,val,pos;
bool operator <(const node & a)const
{
return val < a.val || (val == a.val && pos > a.pos);
}
}st;
int n,m;
int a[maxn],vis[maxn],index[maxn];
priority_queue<node> pq;
int main()
{
int T,C = 1;
//scanf("%d",&t);
while(scanf("%d%d",&m,&n) && (n+m))
{
memset(vis,0,sizeof(vis));
while(!pq.empty())
pq.pop();
int ans = 0,num = 0;
for(int i = 0; i < n; i++)
{
int x;
scanf("%d",&x);
if(num < m)
{
if(!vis[x])
{
st.x = x;
st.val = 1;
st.pos = i;
index[x] = i;
num++;
}
else
{
st.x = x;
st.val = vis[x] + 1;
st.pos = index[x];
}
vis[x]++;
pq.push(st);
}
else
{
if(vis[x])
{
vis[x]++;
st.x = x;
st.val = vis[x];
st.pos = index[x];
pq.push(st);
}
else
{
while(vis[pq.top().x] != pq.top().val || index[pq.top().x] != pq.top().pos)
pq.pop();
vis[pq.top().x] = 0;
pq.pop();
ans++;
st.x = x;
st.val = 1;
st.pos = i;
pq.push(st);
index[x] = i;
vis[x] = 1;
}
}
}
printf("Case %d: %d\n",C++,ans);
}
return 0;
}