• 杂题 [Tjoi 2013]松鼠聚会


    问题 F: [Tjoi 2013]松鼠聚会
    时间限制: 1 Sec 内存限制: 128 MB
    提交: 70 解决: 35
    [提交][状态][讨论版]
    题目描述
    有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。

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

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

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

    题目中要求的是切比雪夫距离,但这个太麻烦了。其实切比雪夫距离是可以转化成曼哈顿距离的,切比雪夫距离公式:S=max(ax-bx,ay-by)等于(ax+ay,ax-ay)和(bx+by,bx-by)两点的曼哈顿距离。想要证明只要把那个曼哈顿距离求出来化简即可。
    那么就容易了,搞一个前缀和,二分出做减法的边界,扫一遍就行了。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #define N 100005
    #define inf 1000000000
    #define ll long long
    struct node{int x,y;}a[N];
    int n,mn=inf,mx=-inf,bx[N],by[N];ll ans=inf*10000000ll,sumx[N],sumy[N];
    using namespace std;
    int main()
    {
        scanf("%d",&n);int x,y;
        for(int i=1;i<=n;i++)
        {
           scanf("%d%d",&x,&y);
           a[i].x=x+y,a[i].y=x-y;
           bx[i]=a[i].x;by[i]=a[i].y;
        }
        sort(bx+1,bx+n+1);
        sort(by+1,by+n+1);
        for(int i=1;i<=n;i++)
           sumx[i]=sumx[i-1]+bx[i],sumy[i]=sumy[i-1]+by[i];
        for(int i=1;i<=n;i++)
        {
            ll h=0;ll l;
            l=lower_bound(bx+1,bx+n+1,a[i].x)-bx;
            h+=(l*2-n)*a[i].x*1ll-sumx[l]*2+sumx[n];
            l=lower_bound(by+1,by+n+1,a[i].y)-by;
            h+=(l*2-n)*a[i].y*1ll-sumy[l]*2+sumy[n];
            if(h<ans)ans=h;
        }
        printf("%lld
    ",ans/2);
    }
  • 相关阅读:
    线程池:
    C#:实现托盘
    Linux内核 TCP/IP、Socket参数调优
    redis配置文件redis.conf参数说明
    redis安装与参数说明
    巧用linux服务器的/dev/shm/,如果合理使用,可以避开磁盘IO不给力,提高网站访问速度。
    mkdir:批量创建文件夹
    linux下的shell运算(加、减、乘、除)
    Linux查看文件编码格式及文件编码转换
    解决vi/vim中粘贴会在行首多很多缩进和空格的问题
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7688760.html
Copyright © 2020-2023  润新知