背景: 如果有一个数轴,数轴上有若干个点。要在数轴上找一点,使得它到各个点的距离之和最短。
结论: 中位数就是最优解。中位数有这样的性质 :所有数与中位数的绝对差之和最小。中位数是数列中间的那个数,或者是中间的那两个数之一。
题目链接:AcWing 104. 货仓选址
代码实现:
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int n, a[maxn];
int main(){
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]);
//此处a[i] - a[i/2]也可以过,数学上看是等价的但不推荐这么写
printf("%d", res);
return 0;
}
//使用nth_element()的写法
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int n, a[maxn];
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++ ) scanf("%d", &a[i]);
nth_element(a, a + n/2, a + n);
//第一个参数是第一个迭代器,第三个参数是最后一个迭代器的后一位,中间参数是你需要的哪一位,时间复杂度O(n)
sort(a, a+n);
int res = 0;
for(int i = 0; i < n; i++ ) res += abs(a[i] - a[n/2]);
printf("%d", res);
return 0;
}
其它拓展:3167. 星星还是树
补充:
- 除了用
sort()
完整排序再找中位数外,可以用nth_element()
直接找中位数