最初做题思路:
知道中位数的方向,但是由于是多个数字所以对于该题不能AC,原本是直接将
两个数取中位数然后该中位数在继续和下一个的输入数字取中位数一直到第n个数据
这样经过y总的讲解后数学的等式不一定成立所以会有bug
正确思路证明:
设仓库的地址坐标为x其余各商店的地址分别为x1,x2,x3……,xn
f(x)=|x1-x|+|x2-x|+|x3-x|…………+|xn-x| 将第一个和第n个为一组,第二个和第n-1个为一组以此类推
=(|x1-x|+|xn-x|)+(|x2-x|+|xn-1-x|)+…………+(若n为奇数则是最中间一个数)/若为偶数则是最中间两个数
=(xn-x1)+(xn-1 - x2)+…………+()
什么时候取等号呢?
当x位于xi 和 xn+1-i 之间时,本题要求的全局最优解而非局部最优解,所以x必须在()中的两个数中间
所以可以分为两种情况:
1、当n是奇数时,x为排序后xi的中位数 mid=res[n/2]
2、当n是偶数时,x为最中间两个数的中位数 mid=(res[n/2]+res[n/2-1])
但是这两种情况可以归纳为一种即mid=res[n/2] 即当n是偶数时x是最中间两个数中的一个数,也可以实现
|xi-x|+|xj-x|=|xj-xi|
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int res[N];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>res[i];
}
int mid;
sort(res,res+n);
/* if(n%2){
mid=res[n/2];
}
else{
mid=(res[0]+res[n-1])/2;
}*/
mid=res[n/2];
int sum=0;
for(int i=0;i<n;i++){
sum+=abs(res[i]-mid);
}
cout<<sum;
return 0;
}