1. 程式人生 > >bzoj3210 花神的澆花集會 坐標

bzoj3210 花神的澆花集會 坐標

define 切比雪夫距離 max res min body 求一個 相同 不同的

題目大意:給定平面上的n個點,求一個點到這n個點的切比雪夫距離之和最小

與3170不同的是這次選擇的點無需是n個點中的一個

首先將每個點(x,y)變為(x+y,x-y) 這樣新點之間的曼哈頓距離的一半就是原點之間的切比雪夫距離

由於曼哈頓距離中橫縱坐標不互相幹擾,因此我們可以將橫縱坐標分開處理

每一維要選一個坐標 到其他所有坐標的絕對值之和相等 很容易想到中位數

但是直接選擇中位數得到的點可能橫縱坐標奇偶性不同 這樣代回原點中發現不是整點

因此如果得到的點橫縱坐標奇偶性相同直接輸出距離 不同的話選擇周圍的四個點進行判定 選擇最小的距離輸出即可

 1 #include<cstring>
 2
#include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdio> 6 7 #define ll long long 8 #define N 100007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch<0||ch>9){if (ch==-) f=-1;ch=getchar();}
14 while(ch>=0&&ch<=9){x=(x<<3)+(x<<1)+ch-0;ch=getchar();} 15 return x*f; 16 } 17 18 int n; 19 int x[N],y[N]; 20 double a[N],b[N]; 21 ll ans=1e60; 22 23 void solve(int kx,int ky) 24 { 25 ll res=0; 26 for (int i=1;i<=n;i++) 27 res+=max(abs(kx-a[i]),abs(ky-b[i]));
28 ans=min(res,ans); 29 } 30 int main() 31 { 32 n=read(); 33 for (int i=1;i<=n;i++) 34 { 35 a[i]=read(),b[i]=read(); 36 x[i]=(a[i]+b[i])*0.5,y[i]=(a[i]-b[i])*0.5; 37 } 38 sort(x+1,x+n+1),sort(y+1,y+n+1); 39 int kx=x[n/2]+y[n/2+1],ky=x[n/2+1]-y[n/2+1]; 40 for (int i=kx-1;i<=kx+1;i++) 41 for (int j=ky-1;j<=ky+1;j++) solve(i,j); 42 printf("%lld",ans); 43 }

bzoj3210 花神的澆花集會 坐標