引例:
位于一条笔直的公路的一边上有N村庄。用一条数轴来描述这条公路,每个村庄都有一个整数坐标。两个村庄的距离定义为他们坐标差的绝对值。现在需要在某个村庄里修建一个邮局,那么这个邮局应修建在那个村庄才能使得各村庄到邮局的距离总和最小。
【输入格式】
第一行是一个整数n,村庄个数。接下来的n行,每行一个整数x[i],表示村庄i的坐标。
【输出格式】
一个整数,表示距离总和的最小值。
【输入样例】
5
7
1
10
6
3
【输出样例】
13
【数据范围】
N<=30000 , 整数坐标(<=1000000)
- 暴力穷举:O(n^2)
- 利用中位数原理:
N 个有序数 a[1],a[2],…,a[n],数学上的定义中位数为:
◆当 N 为奇数的时候,中位数mev=a[n/2]
◆当 N 为偶数的时候,中位数mev=a[n/2]/2.0+a[n/2+1]/2.0
计算机中,含有 n 个数据的一组数,按由小到大排序后,中位数是 a[(n+1)/2]。这里(n+1)/2
称为中位点 mp:(中位点的实质就是该点左边的点数 L,右边点数 R,尽量接近|L-R|<=1)
中位数的原理:邮局问题的最小距离总和就是将邮局建立在中位点的村庄上。
下面来不严格证明这个原理。
情况 1:n为奇数,例如 n=5,如下图:
设把邮局建立在中位点 3 号点上的距离总和为 sum,则:
如果改建立在 2 号点上,则 1、2 号点到邮局的距离减少 x[3]-x[2],3,4,5 号点到邮局的距离都
要增加 x[3]-x[2],即:Tmp=sum-2*(x[3]-x[2])+3*(x[3]-x[2])=sum+(x[3]-x[2])>sum
同理可证,若把邮局建立在 1、4、5 号点,都会比 sum 大!
情况2:n为偶数,同理可证。(当 n 为偶数数时,邮局建立在(n+1)/2 和(n+1)/2+1 是一样的)
代码实现:
#include<cstdio>
#include<