AcWing 104. 货仓选址
在一条数轴上有 N 家商店,它们的坐标分别为 A1∼AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数 N。
第二行 N 个整数 A1∼AN。
输出格式
输出一个整数,表示距离之和的最小值。
数据范围
1≤N≤100000,
0≤Ai≤40000
输入样例:
4
6 2 9 1
输出样例:
12
对于这样一条数轴,怎样选点,才能保证那个点到每个点的距离和是最小的?设这个点的位置为x,则距离就是
∣
x
−
1
∣
+
∣
x
−
2
∣
+
∣
x
−
6
∣
+
∣
x
−
9
∣
|x-1|+|x-2|+|x-6|+|x-9|
∣x−1∣+∣x−2∣+∣x−6∣+∣x−9∣对于这个这个带绝对值的函数,求出最小值也不是什么难事,只要让2<=x<=6就可以,最小值为12,且是定值。在其他范围,你求出的距离都会多加一些长度。例如你令x=1.5,那么x到1和2的距离和是1,再加上到6和9的距离和就是13。多出来的这个距离“1”,就是因为多算了2次“0.5”,这两次0.5就是6到1.5和9到1.5产生的。
所以经过上面的解释,这个x只要放在最中间2个数(偶数情况)的范围之间,总和就是最小的。
那奇数情况呢?没有最中间的两个数。
就像这个数轴,没有最中间的2个数,但是有最中间的数,那就是“5”。刚才说过没有这个“5“的情况,5这个数在[2,6]之间,所以干脆直接让x=5再求距离,就是在上面的情况下,再加上x到5的距离“0”。
所以奇数的情况就是找最中间的数,把那个数定为x,再算剩下的点到x的距离。
本质上讲,就是绝对值函数求最小值。
上面我写的解释可能比较繁琐,如果有更好的想法或者已经理解,可以忽略。(这个解释是为了我复习用的 )
下面附上代码
#include<bits/stdc++.h>
using namespace std;
int a[100001];
bool cmp(int i,int j)
{
return i<j;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n,cmp); //相当于在数轴上,把数排好顺序
int res=0;
for(int i=0;i<n/2;i++) //两个点的距离,就是那个大的数减去小的数
{
res=res+a[n-1-i]-a[i]; //这就是2个在顺序上对称的点的距离
}
printf("%d\n",res);
return 0;
}
如果你有任何建议或者批评和补充,请留言指出,不胜感激。