题解: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;
}

posted @ 2025-11-15 11:16  linruicong  阅读(10)  评论(0)    收藏  举报