【Luogu P1168】【Luogu P1801&UVA 501】中位数&黑匣子(Black Box)——对顶堆相关
2024-09-01 18:51:51
Luogu P1168
Luogu P1801
UVA 501(洛谷Remote Judge)
前置知识:堆、优先队列STL的使用
对顶堆
是一种在线维护第\(k\)小的算法。
其实就是开两个堆,一个是大根堆,一个是小根堆。两个堆的根相对。
下面借助题目P1168进行详细分析。
P1168
题意很好理解,不多作分析。
显然当\(i=1\)时,中位数就是\(a[1]\),记为\(mid\)。
我们可以使用对顶堆,把比\(mid\)小的存入大根堆,比mid大的存入小根堆。
当我们已经加入奇数个元素时,可以根据两个堆的大小调整\(mid\)值
- 当\(heap-big.size==heap-little.size\),当前\(mid\)即为中位数
- 当\(heap-big.size<heap-little.size\),将当前\(mid\)压入大根堆,小根堆的堆顶弹出并作为新的mid,重复以上过程直至\(heap-big.size==heap-little.size\)。
- 反之同理
那么这样不断操作就可以求出答案了。
#include<cstdio>
#include<queue>
using namespace std;
priority_queue<int> que1;//大根堆
priority_queue<int,vector<int>,greater<int>> que2;//小根堆
int n,a,mid;
int main()
{
scanf("%d",&n);
scanf("%d",&a);
mid=a;
printf("%d\n",a);
for (int i=2;i<=n;i++)
{
scanf("%d",&a);
if (a>mid) que2.push(a);
if (a<=mid) que1.push(a);
if (i%2==1)
{
if (que1.size()!=que2.size())
{
//不用while是因为两个堆的大小最多相差2。
if (que1.size()>que2.size())
{
que2.push(mid);
mid=que1.top();
que1.pop();
}
else
{
que1.push(mid);
mid=que2.top();
que2.pop();
}
}
printf("%d\n",mid);
}
}
return 0;
}
P1801&UVA 501
思路类似,不再重复
P1801
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
priority_queue<int,vector<int>,greater<int> > que2;
priority_queue<int,vector<int>,less<int> > que1;
int m,n,a[200005],T,u[200005];
int main()
{
//scanf("%d",&T);
T=1;
/*这是根据UVA 501修改的,两题其实是一样的,但是UVA 501有多组数据,且对输出格式
有要求*/
while (T--)
{
while (!que1.empty()) que1.pop();
while (!que2.empty()) que2.pop();
memset(a,0,sizeof(a));
memset(u,0,sizeof(u));
scanf("%d%d",&m,&n);
for (int i=1;i<=m;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
scanf("%d",&u[i]);
int j=1,now=u[1];
for (int i=1;i<=m;i++)
{
if (que1.empty()) que1.push(a[i]);
else if (a[i]<que1.top()) que1.push(a[i]);
else que2.push(a[i]);
if (i==now)
{
while (i==now)
{
while (que1.size()<j)
{
que1.push(que2.top());
que2.pop();
}
while (que1.size()>j)
{
que2.push(que1.top());
que1.pop();
}
printf("%d\n",que1.top());
j++;
now=u[j];
if (j>n) return 0;
}
}
}
if (T) printf("\n");
}
return 0;
}
UVA 501
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
priority_queue<int,vector<int>,greater<int> > que2;
priority_queue<int,vector<int>,less<int> > que1;
int m,n,a[200005],T,u[200005];
int main()
{
scanf("%d",&T);
while (T--)
{
while (!que1.empty()) que1.pop();
while (!que2.empty()) que2.pop();
memset(a,0,sizeof(a));
memset(u,0,sizeof(u));
scanf("%d%d",&m,&n);
for (int i=1;i<=m;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
scanf("%d",&u[i]);
int j=1,now=u[1];
for (int i=1;i<=m;i++)
{
if (que1.empty()) que1.push(a[i]);
else if (a[i]<que1.top()) que1.push(a[i]);
else que2.push(a[i]);
if (i==now)
{
while (i==now)
{
while (que1.size()<j)
{
que1.push(que2.top());
que2.pop();
}
while (que1.size()>j)
{
que2.push(que1.top());
que1.pop();
}
printf("%d\n",que1.top());
j++;
now=u[j];
if (j>n) break;
}
if (j>n) break;
}
if (j>n) break;
}
if (T) printf("\n");
}
return 0;
}
最新文章
- Linux Shell中单引号、双引号、反引号的区别【转载】
- MongoDB - basic
- 11.10 Taolu1234组信息汇总
- Asp.Net回车键触发Button的OnClick事件解决方案
- <;if>;<;else/>;<;/if>; 语句
- 使用git Rebase让历史变得清晰
- JS实现星级评分
- php Ajax 局部刷新
- 总结iframe高度自适应,自适应子页面高度
- jsp中导入导出excel,ssh框架
- hbase namespace问题
- 【one day one linux】好用的数据处理工具awk
- VR全景智慧城市:VR全景技术分析与研究
- [python标准库]Pickle模块
- CNN中减少网络的参数的三个思想
- ipython 编辑器 jupyter notebook如何将 ipynb 转成 py 并在 jupyter notebook 中继续引用
- js并归排序的思路
- flask框架----flask-script组件
- Gym 101246D	Fire in the Country(dfs求SG函数)
- 80端口未被占用,无法启动wamp的解决方法(原创)
热门文章
- zepto源码分析&#183;整体架构
- PhpStorm10和Apache24配置多项目开发环境
- MyEclipse 2013配置JDBC连接mySQL||Tomcat 7.0 8.0 配置 JDBC |配置mysql-connector-java-5.1.16
- Java11新特性 - Epsilon GC和ZGC
- JVM(5) 类加载机制
- linux虚拟机(centos7)常见配置解析
- 从函数计算架构看 Serverless 的演进与思考
- JVM参数及调优
- Redis bin目录和info命令
- sql中实现先排序后分组