AcWing 104. 货仓选址

该博客讨论了如何在数轴上选择一个点作为货仓位置,以使货仓到所有商店的距离之和最小。通过分析绝对值函数,得出在偶数个商店情况下,货仓应位于最中间两个数之间;在奇数个商店时,货仓应位于最中间的数处。通过排序和计算,给出了一种有效的算法来解决这个问题。
摘要由CSDN通过智能技术生成

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| x1+x2+x6+x9对于这个这个带绝对值的函数,求出最小值也不是什么难事,只要让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;
}

如果你有任何建议或者批评和补充,请留言指出,不胜感激。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值