在一条数轴上有 N N N 家商店,它们的坐标分别为 A 1 A_1 A1∼ A N A_N AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数 N N N。
第二行 N N N 个整数 A 1 A_1 A1∼ A N A_N AN。
输出格式
输出一个整数,表示距离之和的最小值。
数据范围
1 ≤ N ≤ 100000 1≤N≤100000 1≤N≤100000,
0 ≤ A i ≤ 40000 0≤A_i≤40000 0≤Ai≤40000
输入样例
4
6 2 9 1
输出样例
12
设 f ( x ) f(x) f(x)表示把货仓建在 x x x位置时距离之和的最小值,那么:
f ( x ) = ∣ X 1 − x ∣ + ∣ X 2 − x ∣ + . . . + ∣ X n − x ∣ f(x) = |X_1 - x| + |X_2 - x| + ... + |X_n - x| f(x)=∣X1−x∣+∣X2−x∣+...+∣Xn−x∣
分组,将第一项和最后一项分一组,第二项和倒数第二项一组…,那么
f ( x ) = ( ∣ X 1 − x ∣ + ∣ X n − x ∣ ) + ( ∣ X 2 − x ∣ + ∣ X n − 1 − x ∣ ) + . . . f(x) = (|X_1 - x| + |X_n - x|) + (|X_2 - x| + |X_{n-1} - x|) + ... f(x)=(∣X1−x∣+∣Xn−x∣)+(∣X2−x∣+∣Xn−1−x∣)+...
因为:
∣ X 1 − x ∣ + ∣ X n − x ∣ > = X n − X 1 . . . |X_1 - x| + |X_n - x| >= X_n - X_1 ... ∣X1−x∣+∣Xn−x∣>=Xn−X1...
所以:
f ( x ) > = X n − X 1 + X n − 1 − X 2 . . . f(x) >= X_n - X_1 + X_{n-1} - X_2... f(x)>=Xn−X1+Xn−1−X2...
如果
f ( x ) = X n − X 1 + X n − 1 − X 2 . . . , f(x) = X_n - X_1 + X_{n-1} - X_2..., f(x)=Xn−X1+Xn−1−X2...,
则 f ( x ) f(x) f(x)为最小值。那么 x x x 建在中位数的位置,即 a [ n / 2 ] a[n / 2] a[n/2]时,满足距离之和的最小值。此时 a [ n / 2 ] a[n / 2] a[n/2]为序列的中位数。
中位数(Median)又称中值,指按顺序排列的一组数据中居于中间位置的数。
#include
#include
#include
using namespace std;
const int N = 100010;
int a[N];
int main(){
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
sort(a, a + n);
int res = 0;
for(int i = 0; i < n; i++) res += abs(a[i] - a[n / 2]);
printf("%d\n", res);
return 0;
}