51nod 1096 距离之和最小 1108 距离之和最小 V2
Posted driverlao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1096 距离之和最小 1108 距离之和最小 V2相关的知识,希望对你有一定的参考价值。
【题解】
很显然在一条坐标轴上到各个点距离之和最小的点就是它们的中位数。怎么证明呢?我们假设现在找的某个点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 ",ans); 37 return 0; 38 }
以上是关于51nod 1096 距离之和最小 1108 距离之和最小 V2的主要内容,如果未能解决你的问题,请参考以下文章