有一道题大概是这样的:有n条水平的线,知道线的纵坐标,选择一条线,使得这条线到所有线的距离之和最小。
根据数学知识,我们知道,如果线是奇数条的话,那么中间那条(纵坐标的中位数)即可,如果是偶数条的话,那么中间那2条区间内的都可以,而如果要线的纵坐标尽可能小,那么就取中间两条纵坐标较小的那条即可。
那么在线数量为偶数的时候,这并不是传统的求中位数问题,而线数量为奇数的时候,则变成传统的中位数问题。
求中位数的方法可以先排序然后直接取中间的一条即可,但是对于大数据量来说,排序不可行。利用线性时间选择可以再O(n)下找到中位数。
线性时间选择将数组分成3部分,一部分是基准(1个数),其他两部分是大于这个基准的数组和小于基准的这个数组,对于长度为n的数组来说,我们目的是找到第k=(1+n)/2个数,那么就可以根据k和基准的关系来判断第二次是在小于基准的数组里查找还是在大于基准里的数组查找。程序如下:
#include<iostream>
using namespace std;
#define MAX 100001
int main()
{
int a[MAX];
int *p=a;
int x,y,t1,n=0;
char t2;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
int* small=new int[n]; //小于中位数的集合
int* big=new int[n]; //大于中位数的集合
int equal; //等于中位数的那个数,也就是基准
i