• Evanyou Blog 彩带


      题目传送门

    松鼠聚会

    题目描述

    草原上住着一群小松鼠,每个小松鼠都有一个家。时间长了,大家觉得应该聚一聚。但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理。

    每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为点(x,y)和它周围的8个点(x-1,y)(x+1,y),(x,y-1),(x,y+1).(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)距离为1。

    输入输出格式

    输入格式:

     

    第一行是一个整数N,表示有多少只松鼠。接下来N行,第i行是两个整数x和y,表示松鼠i的家的坐标

     

    输出格式:

     

    一个整数,表示松鼠为了聚会走的路程和最小是多少。

     

    输入输出样例

    输入样例#1: 
    6
    -4 -1
    -1 -2
    2 -4
    0 2
    0 3
    5 -2
    输出样例#1: 
    20
    输入样例#2: 
    6
    0 0
    2 0
    -5 -2
    2 -2
    -1 2
    4 0
    输出样例#2: 
    15

    说明

    样例解释

    在第一个样例中,松鼠在第二只松鼠家(-1,-2)聚会;在第二个样例中,松鼠在第一只松鼠家(0.0)聚会。

    数据范围

    30%的数据,0 ≤ N ≤ 1000

    100%的数据,0 ≤ N ≤ 100000; −10^9 ≤ x, y ≤ 10^9


      分析:

      这道奇妙的题让蒟蒻认识了切比雪夫距离这个奇妙的东西,关于切比雪夫距离可以参照julao的博客

      关于这道题,我们把切比雪夫距离转换成曼哈顿距离,然后用前缀和+二分答案优化一下就可以了。

      Code:

    //It is made by HolseLee on 6th Nov 2018
    //Luogu.org P3964
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N=1e5+7;
    int n,x[N],y[N],px[N],py[N];
    ll sumx[N],sumy[N],ans;
    
    inline int read()
    {
        char ch=getchar(); int x=0; bool flag=false;
        while( ch<'0' || ch>'9' ) {
            if( ch=='-' ) flag=true; ch=getchar();
        }
        while( ch>='0' && ch<='9' ) {
            x=x*10+ch-'0'; ch=getchar();
        }
        return flag ? -x : x;
    }
    
    void getsum()
    {
        for(int i=1; i<=n; ++i) sumx[i]=sumx[i-1]+x[i];
        for(int i=1; i<=n; ++i) sumy[i]=sumy[i-1]+y[i];
    }
    
    inline ll binary_x(int u)
    {
        ll l=1, r=n, mid,ret=n;
        while( l<=r ) {
            mid=(l+r)>>1;
            if( x[mid]<=px[u] ) ret=mid, l=mid+1;
            else r=mid-1;
        }
        return ret;
    }
    
    inline ll binary_y(int u)
    {
        ll l=1, r=n, mid,ret=n;
        while( l<=r ) {
            mid=(l+r)>>1;
            if( y[mid]<=py[u] ) ret=mid, l=mid+1;
            else r=mid-1;
        }
        return ret;
    }
    
    inline ll getans(int u)
    {
        ll xpos=binary_x(u);
        ll ansx=xpos*px[u]-sumx[xpos]+sumx[n]-sumx[xpos]-(n-xpos)*px[u];
        ll ypos=binary_y(u);
        ll ansy=ypos*py[u]-sumy[ypos]+sumy[n]-sumy[ypos]-(n-ypos)*py[u];
        return ansx+ansy;
    }
    
    int main()
    {
        n=read(); int a,b;
        for(int i=1; i<=n; ++i) {
            a=read(), b=read();
            x[i]=px[i]=a+b; y[i]=py[i]=a-b;
        }
        sort(x+1,x+n+1); sort(y+1,y+n+1);
        getsum();
        ans=1e18;
        for(int i=1; i<=n; ++i) {
            ll now=getans(i);
            ans=min(now,ans);
        }
        printf("%lld
    ",ans>>1ll);
        return 0;
    }
  • 相关阅读:
    Ubuntu下的解压缩
    Android开机动画
    Android 5.0源码编译问题
    ubuntu学习的简单笔记
    全局变量:global与$GLOBALS的区别和使用
    Java语言中的面向对象特性总结
    c/c++常见面试题
    查数据库中的表,了解大体结构
    PHP数组详解
    HTML5新增及移除的元素
  • 原文地址:https://www.cnblogs.com/cytus/p/9917489.html
Copyright © 2020-2023  润新知