2016算法第一次练习赛——B 朴素的中位数

B 朴素的中位数

时间限制:1000ms   内存限制:65536kb

题目描述

两个有序数组num1和num2,均是从小到大排列,长度分别为n和m。找出这两个数组的中位数。

输入

两个整数n,m,分别为数组num1和num2的长度(0<=n,m<=1000000)

接下来n个数为num1中的整数。

然后m个数为num2中的整数。

输出

对于每组数据,输出两个数组的中位数。偶数情况下输出中间两个数的平均数。均保留小数点后一位。若两个数组均为空,输出0.0。

输入样例

2 1
1 3
2
2 2
1 2
3 4

输出样例

2.0
2.5

HINT

如果wa的很奇怪,那可能是……数据会超过int范围

题目分析

  首先,本题要声明三个大容量的数组,为了避免出现内存方面的问题,应该声明在函数外面。

  然后,我们开始分析这个题目,对于给定的这两个数组num1、num2,它们各自都是从小到大排列好的,这就需要我们换一种思路去找中位数,而不是将两个数组再重新组合排序了。
  一组排好序的数据的中位数,一定是出现在这组数据的中间位置的,我们只要找到位于该位置处的数据即可。
  我们可以设置一个储存数据的数组a,然后从num1、num2数组的初始位置开始,依次把较小的数据存入数组a中,并记录好a中已有数据的个数k,直到k等于(n+m)/ 2(n+m为偶数)或(n+m-1)/2(n+m为奇数)。

示例代码

#include<cstdio>
long long num1[1000008],num2[1000007],a[2000001];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {

        for(int i=0; i<n; i++)
        {
            scanf("%lld",&num1[i]);
        }
        for(int i=0; i<m; i++)
        {
            scanf("%lld",&num2[i]);
        }
        if(n==0&&m==0)
        {
            printf("0.0\n");
        }
        else
        {
            int i=0,j=0;
            int k;
            if((n+m)%2==0)
                k=(n+m)/2;
            else
                k=(n+m-1)/2;
            for(int t=0; t<=k; t++)
            {
                if(i==n)
                {
                    a[t]=num2[j];
                    if(j<m)
                        j++;
                }
                else if(j==m)
                {
                    a[t]=num1[i];
                    if(i<n)
                        i++;
                }
                else if(num1[i]<num2[j])
                {
                    a[t]=num1[i];
                    if(i<n)
                        i++;
                }
                else
                {
                    a[t]=num2[j];
                    if(j<m)
                        j++;
                }
            }
            if((n+m)%2==0)
            {
                double o1=a[(n+m)/2],o2=a[(n+m)/2-1];
                double ans=(o1+o2)/2;
                printf("%.1lf\n",ans);
            }
            else
            {
                double ans2;
                ans2=a[(n+m-1)/2];
                printf("%.1lf\n",ans2);
            }
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值