寻找中位数

寻找中位数

TimeLimit:1000MS  MemoryLimit:128MB

64-bit integer IO format:%lld

已解决 | 点击收藏

×

收藏题目

备注

Close确定

Problem Description

这题温暖大家的心(手动滑稽.jpg我看能收割多少个wa)

给定n个整数,求这些整数的中位数。

注意:若n为偶数,输出从小到大排序后最中间的两个数的平均数向下取整的结果.

其中向下取整的定义 :x的向下取整 = 不大于x的最大整数

Input

单组数据

第一行包含一个整数n,代表有n的整数

接下来一行有n个整数 a1,a2,a3……an

1<=n<=106

保证所有整数都在int 范围内。

后台共有4组n=1e6级别的大数据。

测评机的测评时间,是累加所有测试点的耗时的

Output

输出一个整数代表中位数

SampleInput

4 -4 -2 -1 -3

SampleOutput

-3
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
#define nth(k,n) nth_element(a,a+k,a+n);  // 将 第K大的放在k位
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int n,a[2000005];
int main() {
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        a[i]=read();
    }
    if(n&1){
        nth(n/2,n);
        printf("%d\n",a[n/2]);
    }
    else{
        nth(n/2-1,n);
        double s1=(double)a[n/2-1];
        nth(n/2,n);
        double s2=(double)a[n/2];
        printf("%d\n",(int)floor((s1+s2)/2.0));
    }
    return 0;
}

 

### 中位数算法实现 中位数是指一组数据按大小顺序排列后处于中间位置的数值。如果数据数量为奇数,则中位数是正中间的那个值;如果是偶数,则中位数通常是中间两个数的平均值。 下面是一个基于快速选择(Quickselect)算法的 C 实现,用于找到数组中的中位数[^1]: ```c #include <stdio.h> // 交换两个整数 void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } // 划分函数,类似于快速排序中的划分操作 int partition(int arr[], int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j <= high - 1; j++) { if (arr[j] <= pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return i + 1; } // 快速选择算法的核心部分 int kthSmallest(int arr[], int l, int r, int k) { if (k > 0 && k <= r - l + 1) { int pos = partition(arr, l, r); if (pos - l == k - 1) return arr[pos]; if (pos - l > k - 1) return kthSmallest(arr, l, pos - 1, k); else return kthSmallest(arr, pos + 1, r, k - pos + l - 1); } return INT_MAX; } double findMedian(int arr[], int n) { if (n % 2 == 1) { return kthSmallest(arr, 0, n - 1, n / 2 + 1); // 奇数情况返回第 (n/2)+1 小的元素 } else { int first = kthSmallest(arr, 0, n - 1, n / 2); // 找到第一个中间值 int second = kthSmallest(arr, 0, n - 1, n / 2 + 1); // 找到第二个中间值 return ((double)(first + second)) / 2.0; // 返回它们的平均值 } } int main() { int arr[] = {9, 5, 7, 1, 3}; int n = sizeof(arr) / sizeof(arr[0]); double median = findMedian(arr, n); printf("Median: %.2lf\n", median); return 0; } ``` 上述代码实现了快速选择算法来高效地中位数。对于更复杂的场景或者需要保证最坏情况下性能稳定的情况,可以考虑 BFPRT 算法(即“中位数中位数”算法),其时间复杂度为 \(O(n)\)[^3]。 #### 关于 y 轴上的最佳位置问题 在某些实际应用中,比如寻找最优加油站的位置等问题,通常可以通过计算给定点集中某维度(如 y 坐标)的中位数作为目标位置的选择依据[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值