zoukankan      html  css  js  c++  java
  • BZOJ

    pro:  有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。0<=N<=10^5  ,-10^9<=x,y<=10^9  

    sol:   常识告诉我们,8个反向距离相同,等价于切比雪夫距离。 为了方便统计距离,转化为曼哈顿距离。 此题是找一只松鼠家作为中心点,所以不是分别求中位数。

    而是枚举每个松鼠,快速计算其他松鼠到他的距离,而快速统计只需要分类正负即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=400010;
    int x[maxn],y[maxn];ll sum[maxn],ans;
    ll sumx[maxn],sumy[maxn];
    struct point{ int x,y;}s[maxn];
    bool cmpx(point w,point v){ return w.x<v.x; }
    bool cmpy(point w,point v){ return w.y<v.y; }
    int main()
    {
        int N;
        scanf("%d",&N);
        rep(i,1,N){
            ll tx,ty;
            scanf("%d%d",&tx,&ty);
            s[i].x=tx+ty; s[i].y=tx-ty;
        }
        sort(s+1,s+N+1,cmpx);
        rep(i,1,N) x[i]=s[i].x,sumx[i]=sumx[i-1]+s[i].x;
        sort(s+1,s+N+1,cmpy);
        rep(i,1,N) y[i]=s[i].y, sumy[i]=sumy[i-1]+s[i].y;
        rep(i,1,N) {
            ll tmp=0; int pos;
            pos=lower_bound(x+1,x+N+1,s[i].x)-x;
            tmp+=1LL*(pos-1)*s[i].x-sumx[pos-1]+(sumx[N]-sumx[pos-1])-1LL*(N-pos+1)*s[i].x;
            pos=lower_bound(y+1,y+N+1,s[i].y)-y;
            tmp+=1LL*(pos-1)*s[i].y-sumy[pos-1]+(sumy[N]-sumy[pos-1])-1LL*(N-pos+1)*s[i].y;
            if(i==1) ans=tmp;
            else ans=min(ans,tmp);
        }
        cout<<ans/2<<endl;
        return 0;
    }
  • 相关阅读:
    C语言II作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
    C语言ll作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10691981.html
Copyright © 2011-2022 走看看