曼哈顿距离,欧几里得距离学习笔记

     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

 

 

转载于:https://www.cnblogs.com/jiecaoer/p/11215781.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值