• bzoj3170 [Tjoi 2013]松鼠聚会


    Description

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

    Input

    第一行给出数字N,表示有多少只小松鼠。0<=N<=10^5 下面N行,每行给出x,y表示其家的坐标。 -10^9<=x,y<=10^9

    Output

    表示为了聚会走的路程和最小为多少。

    首先等价变换,旋转坐标系45度,点(x,y)改为((x+y)/2,(x-y)/2),原距离定义改为曼哈顿距离

    枚举每个点,分别计算其余点与其x,y坐标差之和

    #include<cstdio>
    #include<algorithm>
    char buf[10000005],*ptr=buf-1;
    inline int input(){
        int x=0,c=*++ptr,f=1;
        while(c>57||c<48){if(c=='-')f=-1;c=*++ptr;}
        while(c>47&&c<58)x=x*10+c-48,c=*++ptr;
        return x*f;
    }
    const int N=100500;
    int n;
    int x0[N],y0[N],xv[N],yv[N];
    long long xs[N],ys[N],ans=1ll<<62;
    int main(){
        fread(buf,1,10000000,stdin);
        n=input();
        for(int i=1;i<=n;i++){
            int x=input(),y=input();
            x0[i]=xv[i]=x+y;
            y0[i]=yv[i]=x-y;
        }
        std::sort(xv+1,xv+n+1);
        std::sort(yv+1,yv+n+1);
        for(int i=1;i<=n;i++){
            xs[i]=xs[i-1]+xv[i];
            ys[i]=ys[i-1]+yv[i];
        }
        for(int i=1;i<=n;i++){
            int m=std::lower_bound(xv+1,xv+n+1,x0[i])-xv;
            long long s=(1ll*x0[i]*m-xs[m])+(xs[n]-xs[m]-1ll*x0[i]*(n-m));
            m=std::lower_bound(yv+1,yv+n+1,y0[i])-yv;
            s+=(1ll*y0[i]*m-ys[m])+(ys[n]-ys[m]-1ll*y0[i]*(n-m));
            if(s<ans)ans=s;
        }
        printf("%lld
    ",ans>>1);
        return 0;
    }
  • 相关阅读:
    第31-35课
    Cisco学习笔记
    ScreenOS地址转换
    Bootstrap3组件--2
    Bootstrap3组件--1
    Bootstrap3全局CSS样式
    MySQL数据库中字段含逗号的数据,分隔成多条数据
    EF Core 关联数据
    ABP 创建 webapi
    Abp ajax The required antiforgery request token was not provided in either form field
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5515589.html
Copyright © 2020-2023  润新知