题意: 在一条数轴上有 N 家商店,它们的坐标分别为 A1~AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数N。
第二行N个整数A1~AN。
输出格式
输出一个整数,表示距离之和的最小值。
数据范围
1≤N≤100000
输入样例:
4
6 2 9 1
输出样例:
12
思路:
- 问题可以转化为目标点与a[1]和a[n]之间的距离和,加上目标点与a[2]与a[n - 1]之间的距离和,加上……
- 而对于目标点与其他两点x,y之间的距离和:如果目标点在x,y之间,距离和就为|x - y|;如果目标点在x,y区间的外侧,那么这个距离和绝对>= |x - y|.
- 所以综合起来,要让所有点到目标点的距离和最小,那么目标点的坐标必须是所给序列a的中位数。
代码实现:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#define int long long
#define lowbit(x) (x &(-x))
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double EXP = 1e-8;
const ll MOD = 1e9 + 7;
const int N = 1e6 + 5;
int n, x, ans;
int a[N];
signed main()
{
IOS;
cin >> n;
for(int i = 0; i < n; i ++)
cin >> a[i];
sort(a, a + n);
if(n % 2) x = a[n / 2];
else x = (a[n / 2 - 1] + a[n / 2]) / 2;
for(int i = 0; i < n; i ++)
ans += abs(a[i] - x);
cout << ans << endl;
return 0;
}