问题描述
在一条数轴上有 N N N家商店,它们的坐标分别为 A 1 ∼ A N A1∼AN A1∼AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式:
第一行输入整数 N N N。
第二行 N N N个整数 A 1 ∼ A N A1∼AN A1∼AN。
输出格式:
输出一个整数,表示距离之和的最小值。
数据范围
1
≤
N
≤
100000
,
1≤N≤100000,
1≤N≤100000,
0
≤
A
i
≤
40000
0≤Ai≤40000
0≤Ai≤40000
输入样例:
4
6 2 9 1
输出样例:
12
思路
1、排序,如果n为奇数、则选为中位数,如果n是偶数则选中间两数。
2、最优点就是中位数,如果n为奇数则中位数就是中间的那个数,否则就是中间那两个数。
3、用快速选择算法 选出中位数复杂度可以降低。
C++代码:
写法1 O ( l o g n ) O(logn) O(logn)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int q[N];
int main(){
cin >> n;
for(int i = 0; i < n; i++) cin >> q[i];
sort(q, q + n);
int res = 0;
for(int i = 0; i < n; i++) res += abs(q[i] - q[n >> 1]);
cout << res;
return 0;
}
写法2 O ( l o g n ) O(logn) O(logn)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int q[N];
int main(){
cin >> n;
for(int i = 0; i < n; i++) cin >> q[i];
sort(q, q + n);
int res = 0;
for(int i = 0; i < n; i++) res += abs(q[i] - q[i >> 1]);
cout << res;
return 0;
}
写法3 O ( n ) O(n) O(n)
#include <iostream>
#include <algorithm>
using namespace std;
int n;
const int N = 100010;
int q[N];
int main()
{
cin >> n;
for(int i = 0; i < n; i++) cin >> q[i];
nth_element(q, q + (n >> 1) , q + n);
int res = 0;
for(int i = 0; i < n; i++) res += abs(q[i] - q[n / 2]);
cout << res << endl;
return 0;
}