码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC 1063 秋实大哥与妹子(二叉堆)

时间:2016-05-14 10:19:26      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: 点我跳转~

题意: 求中位数。

注意事项: (1)n最大为250000。 (2)内存限制大小为1500KB。

思路: 由于内存限制,只能开大概 n/2 大小的数组。如果 n 为偶数,排序之后,中位数的位置会出现在 n/2,和 n/2 + 1,

而如果 n 为奇数则中位数的位置在 n/2 + 1,所以数组大小开 n/2 + 1。首先对前 n/2 + 1个数字建立一个大根堆。对于之后的

输入维护这个大根堆。输入完成之后进行排序,根据 n 的奇偶来选择堆中最大,或第一第二大的数字求出中位数。

如果之前会堆排序的话,这道题就差不多可以AC了。

堆排序

 

致中和,天地位焉,万物育焉。秋实大哥是一个追求中庸的人。

虽然秋实大哥的仰慕者众多,但秋实大哥不喜欢极端的妹纸。所以他想从所有仰慕自己的妹纸中挑选出一个符合中庸之道的。

每一个妹纸对秋实大哥的仰慕程度可以用一个整数 ai 来表示,秋实大哥想要找出这些数的中位数。

计算有限个数的数据的中位数的方法是:

把所有的同类数据按照大小的顺序排列。如果数据的个数是奇数,则中间那个数据就是这群数据的中位数;
如果数据的个数是偶数,则中间那2个数据的算术平均值就是这群数据的中位数。

Input

第一行有一个整数 n ,表示秋实大哥的仰慕者数目。

接下来 n 行,每行有一个正整数 ai 。

1≤n≤250000 ,1≤a i <2 ^31  。

Output

输出这n n 个数的中位数,保留一位小数。

Sample input and output

3
1
2
3
2.0

Hint

注意内存大小限制。

代码:

#include <stdio.h>
#include <algorithm>
#define N 125007
using namespace std;
void downAdjust(int  *num, int i, int n)   //对i元素向下找到合适的位置
{
    int lchild, rchild;
    lchild = i * 2;
    rchild = i * 2 + 1;
    int max_i = i;
    if (i <= n/2)
    {
        if (num[lchild] > num[max_i] && lchild <= n)
            max_i = lchild;
        if (num[rchild] > num[max_i] && rchild <= n)
            max_i = rchild;
        if (max_i != i)
        {
            swap(num[i], num[max_i]);
            downAdjust(num, max_i, n);
        }
    }
}
void Build(int *num, int n)    //建立一个大根堆
{
    for (int i = n/2; i >= 1; i--)
        downAdjust(num, i, n);
}
void Sort(int *num, int n)     //堆排序
{
    Build(num, n);
    for (int i = n; i >= 1; i--)
    {
        swap(num[i], num[1]);
        downAdjust(num, 1, i - 1);
    }
}
int main()
{
    int n, num[N];
    while (scanf("%d", &n) != EOF)
    {
        for (int i = 1; i <= n/2 + 1; i++)
        {
            scanf("%d", &num[i]);
        }
        Build(num, n/2 + 1);
        int temp;
        for (int i = n/2 + 2; i <= n; i++)   //对后一半的输入维护大根堆
        {
            scanf("%d", &temp);
            if (temp >= num[1])
                continue;
            num[1] = temp;
            downAdjust(num, 1, n/2 + 1);
        }
        Sort(num, n/2 + 1);
        if (n % 2)
        {
            printf("%.1lf\n", (double)num[n/2 + 1]);
        }
        else
        {
            double ans = num[n/2] >= num[n/2 - 1] ? num[n/2] : num[n/2 - 1];
            ans += (double)num[n/2 + 1];
            ans /= 2.0;
            printf("%.1lf\n", ans);
        }
    }
    return 0;
}

 

UESTC 1063 秋实大哥与妹子(二叉堆)

标签:

原文地址:http://www.cnblogs.com/burning-flame/p/5491951.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!