题解:P12166 [蓝桥杯 2025 省 C/Java A/研究生组] 冷热数据队列
一道模拟题。
题目分析
其实看到第一眼挺像某种 STL 的应用的。略微思考过后发现可以直接用 list 秒了。于是直接开始做。
list 双向链表
没有学过的同学看这里。
双向链表虽然不支持随机访问,但是在任意位置插入或者删除元素非常高效。这里就不多讲了,感兴趣的同学可以自行了解。这里只介绍一些代码中用到的函数。
l.size();与许多容器相同,它是用来求元素个数的。l.push_front(value);在头部添加元素。l.pop_back();删除尾部元素。l.erase(iterator position);删除指定位置元素。l.begin();返回指向第一个元素的迭代器。l.rbegin();返回指向最后一个元素的逆向迭代器。
AC 代码实现
记录。
#include<bits/stdc++.h>
using namespace std;
int n1,n2,m,x,t;
pair<int,list<int>::iterator> d[1000005];//存储位置信息
list<int> q1,q2;//两个双向链表
map<int,bool> vis;//检查是否出现过
int main()
{
scanf("%d%d%d",&n1,&n2,&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
if(vis[x]==false)//没有出现过
{
vis[x]=true;
q2.push_front(x);
d[x].first=2;
d[x].second=q2.begin();
}
else//出现了
{
auto p=d[x];
if(p.first==1) q1.erase(p.second);
else q2.erase(p.second);
q1.push_front(x);
d[x].first=1;
d[x].second=q1.begin();
}
if((int)q1.size()>n1)//对于热数据队列溢出的操作
{
t=*q1.rbegin();
q2.push_front(t);
d[t].first=2;
d[t].second=q2.begin();
q1.pop_back();
}
if((int)q2.size()>n2)//对于冷数据队列溢出的操作
{
t=*q2.rbegin();
vis[t]=0;
q2.pop_back();
}
}
//输出答案
for(auto i:q1) printf("%d ",i);
printf("\n");
for(auto i:q2) printf("%d ",i);
return 0;
}

浙公网安备 33010602011771号