Running Median POJ - 3784 (对顶堆/优先队列 | 链表)
Input
Output
Sample Input
3
1 9
1 2 3 4 5 6 7 8 9
2 9
9 8 7 6 5 4 3 2 1
3 23
23 41 13 22 -3 24 -31 -11 -8 -7
3 5 103 211 -311 -45 -67 -73 -81 -99
-33 24 56
Sample Output
1 5
1 2 3 4 5
2 5
9 8 7 6 5
3 12
23 23 22 22 13 3 5 5 3 -3
-7 -3 题意:每组M个数,然后对于每组数读入的时候,只要读入了奇数个的数,就求出先前读入数的中位数,然后输出 思路:可以采用两个优先队列的做法,如果当前读入的数>当前中位数,插入小根堆,否则插入大根堆,这样实际上就维护了中位数相邻两侧的值。
然后维护 num【小根堆】 - num【大根堆】 <= 1,就是维护中位数两侧的数量应当均分,这样小根堆的top,即是中位数
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std; int t;
int cas,n;
const int maxn = 1e4+;
int ans[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
priority_queue<int,vector<int>,greater<int> >que1;
priority_queue<int,vector<int>,less<int> >que2; scanf("%d%d",&cas,&n);
printf("%d %d\n",cas,n/+);
int tmp;
int l=,r=,num=;
int cnt = ;
for(int i=;i<=n;i++)
{
scanf("%d",&tmp);
if(tmp > num)
{
que1.push(tmp);
r++;
}
else
{
que2.push(tmp);
l++;
}
if(r < l)
{
int f = que2.top();
que2.pop();
que1.push(f);
r++,l--;
}
else if(r > l + )
{
r--,l++;
int f = que1.top();
que1.pop();
que2.push(f);
}
num = que1.top();
if(i&)
{
ans[++cnt] = num;
}
}
for(int i=;i<=cnt;i++)
{
printf("%d",ans[i]);
if(i != cnt && i%!=)printf(" ");
else printf("\n");
}
}
}
链表:
链表主要是个离线处理,先将所有的数据读入,然后记录下其下标。
然后对其排序,记录下在有序序列下,原来下标的数在哪出现。
然后从n~1进行处理,因为n永远是该序列剩余的数中最后出现的,也就是说不会将该数后未输入的数进行计算。 (关于中位数下标pos的移动那,按照写法是有问题的,但是这题上适用)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; int t;
int cas,n;
const int maxn = 1e4+;
struct Node
{
int val;
int next;
int pre;
int index;
}node[maxn];
int p[maxn]; bool cmp(Node a,Node b)
{
return a.val < b.val;
}
int ans[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&cas,&n);
printf("%d %d\n",cas,(n+)>>);
for(int i=;i<=n;i++)
{
scanf("%d",&node[i].val);
node[i].index = i;
}
sort(node+,node++n,cmp);
for(int i=;i<=n;i++)
{
node[i].next = i+;
node[i].pre = i-;
}
node[].pre = node[n].next = -;
for(int i=;i<=n;i++)
{
p[node[i].index] = i;
}
int pos = (n+)>>;
int tot = ;
int l=,r=;
for(int i=n;i>;i--)
{ if(i & )
{
if(l > r)pos = node[pos].next;
else if(l < r)pos = node[pos].pre;
ans[++tot] = node[pos].val;
l=r=;
}
if(p[i] >= pos)r++;
if(p[i] <= pos)l++;
if(node[p[i]].pre != -)
{
node[node[p[i]].pre].next = node[p[i]].next;
}
if(node[p[i]].next != -)
{
node[node[p[i]].next].pre = node[p[i]].pre;
}
}
for(int i=;i<=tot;i++)
{
printf("%d",ans[tot-i+]);
if(i% != && i != tot)printf(" ");
else printf("\n");
}
}
}
Running Median POJ - 3784 (对顶堆/优先队列 | 链表)的更多相关文章
- Running Median POJ - 3784
本题使用对顶堆做法. 为了动态维护中位数,我们可以建立两个堆 :一个大根对,一个小根堆. 用法:在动态维护的过程中,设当前的长度为length,大根堆存从小到大排名 $1 \thicksim \dfr ...
- POJ 2442 Sequence堆 优先队列
题目描述 给定m个序列,每个序列包含n个非负整数.现在我们可以从每个序列中选择一个数字以形成一个具有m个整数的序列.显然,我们可以得到n ^ m种这种序列.然后,我们可以计算每个序列中的数字总和,并获 ...
- POJ 3784.Running Median
2015-07-16 问题简述: 动态求取中位数的问题,输入一串数字,每输入第奇数个数时求取这些数的中位数. 原题链接:http://poj.org/problem?id=3784 解题思路: 求取中 ...
- 【POJ 3784】 Running Median (对顶堆)
Running Median Description For this problem, you will write a program that reads in a sequence of 32 ...
- 【POJ 3784】 Running Median
[题目链接] http://poj.org/problem?id=3784 [算法] 对顶堆算法 要求动态维护中位数,我们可以将1-M/2(向下取整)小的数放在大根堆中,M/2+1-M小的数放在小根堆 ...
- poj3784 Running Median[对顶堆]
由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可 ...
- hdu3282 链表或者对顶堆
维护序列的动态中位数 第一次用链表做题..感觉指针指来指去也挺麻烦的.. 本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对 ...
- POJ3784:Running Median
浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=3784 用一个"对顶堆& ...
- 【POJ3784】Running Median
Running Median Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3406 Accepted: 1576 De ...
随机推荐
- 整合 JIRA 和 Confluence 6
Jira 应用和 Confluence 可以完全的整合在一起.在 Confluence 中收集你项目组成员的想法,知识和计划.在 Jira 中跟踪你的系统出现的问题,让这 2 个应用同时工作. 了解更 ...
- 自定义你的 Confluence 6 站点
本部分对 Confluence 全站进行自定义的相关内容进行了说明.这部分只能是具有 Confluence 的管理员权限的用户才能进行操作 —— 系统管理员或者 Confluence 管理员. 有关对 ...
- Confluence 6 从外部目录中同步数据配置同步间隔
在用户目录(User Directories)界面中显示了最后的系统同步时间,包括有这次同步所花费的时间. 注意:针对 Crowd 和 Jira 目录同步时间的配置只在 Confluence 3.5 ...
- 关于npm 淘宝镜像 以及package.json里包的更新
1.淘宝镜像的设置 npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm ...
- git push -u 用法
在我们第一次提交git的时候: 发现上面用了这个-u参数,也没作解释,特意搜索了下这个-u的用法,加了参数-u后,以后即可直接用git push 代替git push origin master gi ...
- jmeter 获取数据库表数据作为参数
jmeter - 获取数据库表数据作为参数 在jmeter中使用数据库表数据首先需要设置数据库连接,然后在创建JDBC取样器 1.创建配置元件 JDBC Connection Configuratio ...
- 饮冰三年-人工智能-linux-07 硬盘分区、格式化及文件系统的管理
先给虚拟机添加一个硬盘 通过fdisk -l sdb,查看磁盘内容 通过fdisk /sdb 来操作分区 创建一个新分区 创建第二个分区 创建第三个分区 创建扩展分区 再次创建分区,其实使用的是扩展分 ...
- JAVA 代码中使用中文的办法
在编译代码中插入 -encoding UTF-8 示例: javac -encoding UTF-8 *.java
- caffe入门-人脸检测1
最近刚入门caffe,跟着视频做了一个简单人脸检测.包括人脸二分类模型+方框框出人脸. 人脸二分类模型 1. 收集数据 我用的是lfw数据集,总共有13233张人脸图片.非人脸数据有两种选择.1. 用 ...
- python:字符串转换成字节的三种方式及字符转码问题
str='zifuchuang' 第一种 b'zifuchuang'第二种bytes('zifuchuang',encoding='utf-8')第三种('zifuchuang').encode('u ...