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

朴素的中位数

题目链接:https://buaacoding.cn/problem/846/index

分析

题意很简单,就是给定了两个从小到大排好序的数组,找出这两个数组合起来的数据中的中位数。
方法应该比较多,很容易想的比如直接合并成两个数组然后对大数组sort()排序;又因为两个数组都已经是各自有序的了,可以联想一下归并排序中合并数组的方式直接得到有序的大数组,这样会快很多(这也是出这道题的本意);应该也可以用找第k小数的方法利用快排的方式直接找中位数。当然因为没有太卡时间,所以方法随意。
另外:没有指出数组中数据的类型,不注意用了int的话可能得不到全分;以及有数组为空的情况,已经特意指出来了,否则可能会有数组越界等问题。
出错比较多的地方就是在用数组索引求中间数的时候,如果不加注意,a[sum/2-1]就会出现数组下标越界的情况。

代码样例

//Sort版:
#include <iostream>
#include <string.h>
#include <algorithm>
#include<cstdio>
#include<vector>
using namespace std;
vector<long long>v;
int main()
{
    int n,m;
    long long x;
    while(~scanf("%d%d",&n,&m))
    {
        v.clear();
        for(int i = 0;i<n;i++)
        {
            cin>>x;
            v.push_back(x);
        }
        for(int i = 0;i<m;i++)
        {

            cin>>x;
            v.push_back(x);
        }
        sort(v.begin(),v.end());

         double ans = 0.0;
         if(n==0&&m==0)
                ans = 0.0;
            int l = n+m;
          if(l!=0&&l%2==0)
         {
             ans = (double)(v[l/2]+(double)v[l/2-1])/2;
         }
         else if(l%2!=0)
            ans = (double)(v[l/2]);
         printf("%.1lf
",ans);
    }
}

简单给出边合并边排序的方法:
if(n>0&&m>0){
       for(int k=0;k<l;k++)
       {
           if(i<n&&j<m&&num1[i]<=num2[j])
           {
               num3.push_back(num1[i]);
               i++;
           }
           else if(i<n&&j<m&&num2[j]<num1[i])
           {
               num3.push_back(num2[j]);
               j++;
           }
           else if(i<n)
           {
               num3.push_back(num1[i]);i++;
           }
           else if(j<m)
           {
               num3.push_back(num2[j]);j++;
           }
       }

       if(l%2!=0)ans = (double)num3[l/2];
       else ans = (double)(num3[l/2]+(double)num3[l/2-1])/2;
       }
       else{
        if(m==0&&n==0)ans = 0.000;
        else if(m==0&&n!=0)
        {
            if(n%2!=0)ans = (double)num1[n/2];
            else ans = (double)((double)num1[n/2]+(double)num1[n/2-1])/2;
        }
        else{
             if(m%2!=0)ans = (double)num2[m/2];
                else ans = (double)((double)num2[m/2]+(double)num2[m/2-1])/2;
        }
       }
       printf("%.1f
",ans);


算法分析

sort对vector的时间复杂度一般为O(nlogn)
后者边合并边排序的方法只需要O(n)

原文地址:https://www.cnblogs.com/AlvinZH/p/7698964.html