Time Limit: 1 second

Memory Limit: 128 MB

【问题描述】

给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[2], …, A[2k - 1]的中位数。即前1,3,5,……个数的中位数。

【输入格式】

输入文件median.in的第1行为一个正整数N,表示了序列长度。 第2行包含N个非负整数A[i] (A[i] ≤ 10^9)。

【输出格式】

输出文件median.out包含(N + 1) / 2行,第i行为A[1], A[2], …, A[2i – 1]的中位数。

【数据规模】

对于20%的数据,N ≤ 100; 对于40%的数据,N ≤ 3000; 对于100%的数据,N ≤ 100000。

Sample Input1

7
1 3 5 7 9 11 6

Sample Output1

1
3
5 6 【题解】 维护一个大根堆和一个小根堆。 一开始把第一二元素加入到大根堆的第一个位置。然后直接输出第一个元素。 对于之后输入的元素。进行判断。如果大于大根堆的根,则放到小根堆。小于或等于则放到大根堆。 然后放完之后。进行一次判断。看一下这两个堆它们的差的绝对值是否会大于2.如果大于2的话。就把数字 多的那个堆中的根放到另外一个堆中。这样的判断也做完之后。就可以输出中位数了。比如当前i=3,则中 位数的位置就在2,先判断一下2是否等于大根堆的大小,如果是就输出大根堆的根,否则输出小根堆的根。 难点的话在堆的操作上。多熟悉就懂了。 【代码】
#include <cstdio>

int dagendui[100001],xiaogendui[100001],n,pos; //拼音分别对应了大根堆和小根堆 

void up_tiaozheng(int a[100001],int p,int what) //往上调整。 what对应了a堆是什么堆
{ //0为大根堆 1为小根堆
int x = a[p]; //获取需要调整的数字
int i = p,j = p/2; //往上调整 所以是除2表示指向其父亲节点
//printf("p=%d\n",p);
while (j > 0) //如果没有越过树的范围
{
if (what ==0) //大根堆 的调整方法
{
if (x > a[j]) //如果这个值比父亲节点大。那么就不符合大根堆的定义了。
{ //往上走
a[i] = a[j];
i = j;
j = i/2;
}
else //否则就找到了一个合适的位置 直接结束即可。
break;
}
else //小根堆
{
if (x <a[j]) //如果父亲节点比儿子节点大。则不符合小根堆的定义。
{ //同样进行调整
a[i] = a[j];
i = j;
j = i/2;
}
else //如果找到合适的位置就直接结束调整
break;
}
}
a[i] = x;
pos = i; //要记录这个数字最后放到了哪里。
} void down_tiaozheng(int a[100001],int p,int what) //往下调整。
{
int x = a[p]; //获取需要调整的数字。
int i = p,j = p*2;
while (j <=a[0] )
{
if (what ==0) //大根堆
{
if (j < a[0] && a[j+1] > a[j]) //大根堆往下调整的话,儿子要找大的。
j++;
if (x < a[j])
{
a[i] = a[j];
i = j;
j = i*2;
}
else
break;
}
else //小根堆
{
if (j < a[0] && a[j+1] < a[j]) //小根堆要调整则要找小的。
j++;
if (x > a[j])
{
a[i] = a[j];
i = j;
j = i*2;
}
else
break;
}
}
a[i] = x;
} void input_data()
{
scanf("%d",&n);
scanf("%d",&dagendui[1]); //先把第一个元素放到大根堆的根节点。
dagendui[0] = 1;
printf("%d\n",dagendui[1]);
for (int i = 2;i <= n;i++)
{
int dd;
scanf("%d",&dd);//输入的数据和大根堆的根节点比较
if (dd > dagendui[1]) //根据比较的结果放到大根堆或小根堆。
{
xiaogendui[0]++;
xiaogendui[xiaogendui[0]]=dd;
up_tiaozheng(xiaogendui,xiaogendui[0],1); //放到末尾要先向上调整再向下调整
down_tiaozheng(xiaogendui,pos,1);
}
else
{
dagendui[0]++;
dagendui[dagendui[0]] = dd;
up_tiaozheng(dagendui,dagendui[0],0);
down_tiaozheng(dagendui,pos,0); //同理
}
if (dagendui[0] > xiaogendui[0]) //如果它们的大小之差的绝对值大于2则需要调整
{
if ((dagendui[0] - xiaogendui[0]) > 2) //大根堆数字比较多
{ //就把大根堆的根节点放到小根堆中去
xiaogendui[0]++;
xiaogendui[xiaogendui[0]] = dagendui[1];
up_tiaozheng(xiaogendui,xiaogendui[0],1);
down_tiaozheng(xiaogendui,pos,1);
dagendui[1] = dagendui[dagendui[0]];
dagendui[0]--;
down_tiaozheng(dagendui,1,0);
}
}
else
if (dagendui[0] < xiaogendui[0])
{
if ((xiaogendui[0]-dagendui[0]) > 2)
{ //如果小根堆中的数字更多。则把小根堆的根节点放到大根堆中去。
dagendui[0]++;
dagendui[dagendui[0]] = xiaogendui[1];
up_tiaozheng(dagendui,dagendui[0],0);
down_tiaozheng(dagendui,pos,0);
xiaogendui[1] = xiaogendui[xiaogendui[0]];
xiaogendui[0]--;
down_tiaozheng(xiaogendui,1,1);
}
}
if ( (i%2)==1) //如果是奇数 则输出大根堆的根节点或小根堆的根节点。
{
int tt = (i+1)/2;
if (tt ==dagendui[0]) //大根堆的大小和所需要输出的第tt个数字相同就可以直接输出根节点
printf("%d\n",dagendui[1]);
else //否则的话就是放在小根堆的根节点了。
printf("%d\n",xiaogendui[1]);
}
} } int main()
{
//freopen("F:\\rush.txt","r",stdin);
input_data();
return 0;
}

【u119】中位数的更多相关文章

  1. [LeetCode] Find Median from Data Stream 找出数据流的中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  2. [LeetCode] Median of Two Sorted Arrays 两个有序数组的中位数

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  3. BZOJ1303 [CQOI2009]中位数图

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  4. 在MySQL中,如何计算一组数据的中位数?

    要得到一组数据的中位数(例如某个地区或某家公司的收入中位数),我们首先要将这一任务细分为3个小任务: 将数据排序,并给每一行数据给出其在所有数据中的排名. 找出中位数的排名数字. 找出中间排名对应的值 ...

  5. AC日记——中位数 洛谷 P1168

    题目描述 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[2], …, A[2k - 1]的中位数.[color=red]即[/color] ...

  6. [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)

    题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...

  7. LeetCode 4 Median of Two Sorted Arrays 查找中位数,排除法,问题拓展 难度:1

    思路:设现在可用区间在nums1是[s1,t1),nums2:[s2,t2) 1.当一个数组可用区间为0的时候,由于另一个数组是已经排过序的,所以直接可得 当要取的是最小值或最大值时,也直接可得 2. ...

  8. BZOJ 1303 CQOI2009 中位数图 水题

    1303: [CQOI2009]中位数图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2340  Solved: 1464[Submit][Statu ...

  9. 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays

    一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...

随机推荐

  1. .condarc(conda 配置文件)

    Configuration - Conda documentation .condarc以点开头,一般表示 conda 应用程序的配置文件,在用户的家目录(windows:C:\\users\\use ...

  2. 初学者路径规划 | 人生苦短我用Python

    纵观编程趋势 人生苦短,我用Python,比起C语言.C#.C++和JAVA这些编程语言相对容易很多.Python非常适合用来入门.有人预言,Python会成为继C++和Java之后的第三个主流编程语 ...

  3. amazeui学习笔记--css(HTML元素1)--按钮Button

    amazeui学习笔记--css(HTML元素1)--按钮Button 一.总结 1.button的基本使用:a.am-btn 在要应用按钮样式的元素上添加 .am-btn,b.颜色 再设置相应的颜色 ...

  4. WPF 支持分组互斥的 RadioButton 式单选菜单

    扩展 MenuItem 为同组互斥的 RadioMenuItem,并且将对勾符号修改为圆点. http://stackoverflow.com/a/35692688/5972372 这个问题下还有其他 ...

  5. ubuntu,右键添加在终端中打开

    右键中添加"在终端中打开" 在终端输入  sudo apt-get install nautilus-open-terminal 重新启动, 进入操作系统就会发现单击鼠标右键就会出 ...

  6. 初识OpenStack(1)

    初识OpenStack(1) 首先 先来说说我与openstack的渊源吧.那是在上个月中旬.学张的一个朋友给我打电话说让一起来搞一个云平台,当时也不知道是什么.就非常高兴的答应下来了,到了周末,就过 ...

  7. [Tools] Fix Only Committed Files with Prettier and lint-staged

    In this lesson we'll use prettier and lint-staged to run prettier only on files that have been chang ...

  8. 用css3解决移动端页面自适应横屏竖屏的思考

    之前对于横屏的webapp做过一些尝试,可是始终不是非常好的解决方式,前段时间又接触了类似的需求,尝试了感觉更好的解决方式. 之前的方法写的博客:移动网页横竖屏兼容适应的一些体会 这里举的样例还是平时 ...

  9. js如何将字符串作为函数名调用函数

    js将如何字符串作为函数名调用函数 一.总结 一句话总结:用eval来实现.eval可以执行参数字符串. 二.js将字符串作为函数名调用函数 比如我现在有一个字符串str = "func_a ...

  10. 实现拖拽上传文件的一款小控件——dropzone

    由于专注所以专业.非常多小巧的东西乍一看非常不起眼,却在特定的领域表现不俗,就是由于集中了热情. dropzone就是这样一款小控件,实现拖拽上传.它不依赖于其他像jquery等JS库.并且支持多方面 ...