码迷,mamicode.com
首页 > 其他好文 > 详细

51nod 1096 距离之和最小 1108 距离之和最小 V2

时间:2018-09-16 19:45:01      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:def   现在   分享   怎么   else   hid   com   for   lse   

技术分享图片

【题解】

  很显然在一条坐标轴上到各个点距离之和最小的点就是它们的中位数。怎么证明呢?我们假设现在找的某个点x左边有a个点,右边有b个点(a>b)。我们把x向左移动d个单位,并保证x左边依然有a个点,右边依然有b个点,那么现在距离之和减小了ad-bd.  那也就是说,x左右的点数不一样,我们可以通过移动x找到更优的解。那么满足距离之和最小的x的左右两边的点数必须相等,中位数是满足这个条件的。

  n维空间上的曼哈顿距离最小,就是把各个坐标轴分开考虑即可。

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define rg register
 6 #define N 1000010
 7 using namespace std;
 8 int n,mid,x[N],y[N],z[N];
 9 LL ans;
10 inline int read(){
11     int k=0,f=1; char c=getchar();
12     while(c<0||c>9)c==-&&(f=-1),c=getchar();
13     while(0<=c&&c<=9)k=k*10+c-0,c=getchar();
14     return k*f;
15 }
16 int main(){
17     n=read();
18     for(rg int i=1;i<=n;i++) x[i]=read(),y[i]=read(),z[i]=read();
19     sort(x+1,x+1+n); sort(y+1,y+1+n); sort(z+1,z+1+n);
20     if(n&1){
21         mid=x[(n+1)>>1];
22         for(rg int i=1;i<=n;i++) ans+=abs(mid-x[i]);
23         mid=y[(n+1)>>1];
24         for(rg int i=1;i<=n;i++) ans+=abs(mid-y[i]);
25         mid=z[(n+1)>>1];
26         for(rg int i=1;i<=n;i++) ans+=abs(mid-z[i]);
27     }
28     else{
29         mid=(x[n>>1]+x[(n>>1)+1])>>1;
30         for(rg int i=1;i<=n;i++) ans+=abs(mid-x[i]);
31         mid=(y[n>>1]+y[(n>>1)+1])>>1;
32         for(rg int i=1;i<=n;i++) ans+=abs(mid-y[i]);
33         mid=(z[n>>1]+z[(n>>1)+1])>>1;
34         for(rg int i=1;i<=n;i++) ans+=abs(mid-z[i]);
35     }
36     printf("%lld\n",ans);
37     return 0;
38 }
View Code

 

51nod 1096 距离之和最小 1108 距离之和最小 V2

标签:def   现在   分享   怎么   else   hid   com   for   lse   

原文地址:https://www.cnblogs.com/DriverLao/p/9656874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!