曼哈頓距離,歐幾里得距離學習筆記


     1.   定義:

二維下點坐標 ( x , y )

空間里有兩個點( xi , yi )   ( xj , yj )

他們橫坐標距離為 dx = | xi - xj | ,縱坐標距離為 dy = | yi - yj |

他們的切比雪夫距離是橫坐標距離和縱坐標距離中值大的那一個 : max(dx,dy)

曼哈頓距離是橫坐標距離與縱坐標距離的和 : dx+dy

 

 



 

  2.  互相轉換:

    曼哈頓->切比雪夫( x , y ) -> ( (x+y/2) , (x-y/2) )

    這里用換完后的坐標計算曼哈頓,算出來的是原坐標的切比雪夫距離,下面同理。

    切比雪夫->曼哈頓: ( x , y ) -> (    x+y   ,   x-y     )

 


       3.      注意的點:

               兩個點a,b。a到原點的曼哈頓距離為da,b到原點的曼哈頓距離為db,ab兩點的曼哈頓距離為dab,dab,da,db關系不大。切比雪夫同理。

 


       4.      曼哈頓距離最小生成樹:

              


 

   5.     題目:

              bzoj3170: [Tjoi2013]松鼠聚會

                題意:平面上n個點,求所有的點到其中某一個點的切比雪夫距離的最小值。0<=N<=10^5

     做法:切比雪夫->曼哈頓,變成了求所有的點到其中某一個點的曼哈頓距離的最小值。

                          預處理,使得能在o(1)算出某個點到所有點的曼哈頓距離,1~n掃每個點,更新答案即可。

                          怎么預處理?

       單獨考慮x軸時,點k到所有點的距離(x軸上)為(xk-x1)+...+(xk-x(k-1))+(x(k+1)-xk)+...+(xn-xk);

       整理一哈~變成了((k-1)-(n-k) )*xk-(x1+...+x(k-1))+(x(k+1)+...+xn)

          然后(x1+...+x(k-1))就是可愛的前綴和,(x(k+1)+...+xn)就是萌萌噠后綴和拉~

          y軸同理~

        坑點:在數據有點大,注意要先減后加,不然爆long long ,然后Inf要開到1e20

                 代碼:

 1 #include <bits/stdc++.h>
 2 #define nmax 100005
 3 #define inf 1e20
 4  
 5 using namespace std;
 6 typedef long long ll;
 7 ll qzx[nmax]={0},qzy[nmax]={0},ix[nmax],iy[nmax];
 8 struct px{
 9     ll num,id;
10     bool operator < (const px & a) const { return num<a.num; }
11 };
12 px x[nmax],y[nmax];
13  
14 int main(){
15     //freopen("owo.in","r",stdin);
16     ll n,inx,iny,totx=0,toty=0;
17     scanf("%lld",&n);
18     for (int i=1; i<=n; i++) {
19         scanf("%lld%lld",&inx,&iny);
20         x[i].num=(inx+iny);  //先不除以2,后面再解決
21         y[i].num=(inx-iny);
22         totx+=x[i].num;
23         toty+=y[i].num;
24         x[i].id=y[i].id=i;
25     }
26     sort(x+1,x+n+1);
27     sort(y+1,y+n+1);
28     for (int i=1; i<=n; i++) {
29         qzx[i]=qzx[i-1]+x[i].num;
30         qzy[i]=qzy[i-1]+y[i].num;
31         ix[x[i].id]=i;
32         iy[y[i].id]=i;
33     }
34     ll ans=inf;
35     for (int i=1; i<=n; i++) {
36         ll tx=0,ty=0,txi=ix[i],tyi=iy[i];
37         tx-=qzx[txi-1];
38         tx+=(totx-qzx[txi]);
39         tx+=(x[txi].num*(txi-1-n+txi));
40         ty-=qzy[tyi-1];
41         ty+=(toty-qzy[tyi]);
42         ty+=(y[tyi].num*(tyi-1-n+tyi));
43         ans=min(ans,tx+ty);
44     }
45     cout<<ans/2<<endl;
46     return 0;
47 }
View Code

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM