洛谷题单指南-二叉堆与树状数组-P1168 中位数
原题链接:https://www.luogu.com.cn/problem/P1168
题意解读:中位数就是位于中间的数,前1个数的中位数是第1个,前3个数的中位数是第2个,前5个数的中位数的第3个...以此类推。
所以,此题本质上就是动态维护一组数,每1/3/5...等奇数个取第k小的数,取一次后k++。
解题思路:
要动态维护数据,且每次取第k小的数,又有多种做法:快选、平衡树、双堆,这里依然采用双堆做法:
定义一个小根堆,一个大根堆,确保小根堆的堆顶大于大根堆的堆顶,大根堆的元素个数保持在k-1个,这样每次取小根堆的堆顶即是第k小的数。
本题和P1801 黑匣子本质上是一样的。
100分代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, a;
priority_queue<int> q1; //大根堆
priority_queue<int, vector<int>, greater<int>> q2; //小根堆
int cnt;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a;
q1.push(a);
if(q1.size() > cnt) //如果大根堆超过cnt个
{
q2.push(q1.top()); //将大根堆堆顶移至小根堆
q1.pop();
}
if(i % 2 == 1) //每奇数个
{
cout << q2.top() << endl; //输出第cnt+1小的值
cnt++; //cnt下次+1
if(q1.size() < cnt) //如果大根堆不足cnt个
{
q1.push(q2.top()); //将小根堆堆顶移至大根堆
q2.pop();
}
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?