zoukankan      html  css  js  c++  java
  • bzoj3170: [Tjoi2013]松鼠聚会

    题目描述:

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

    思路:

    这题主要就是切比雪夫距和曼哈顿距离的转换。

    对于点 $(x,y)$ 的切比雪夫距离会等于 $(frac{x+y}{2},frac{x-y}{2})$ 。我们把距离转换,两次操作分别按 $x,y$ 排序,统计每个点到所有点的距离和。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=1e5+5;
    int n;LL f1[N],f2[N];
    struct node{
        int v,id;
    }x[N],y[N];
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    bool cmp(node t1,node t2){
        return t1.v<t2.v;
    }
    int main()
    {
        n=read();
        if(n<=1){puts("0");return 0;}
        for(int i=1;i<=n;i++){
            int a=read(),b=read();
            x[i]=(node){a+b,i};
            y[i]=(node){a-b,i};
        }
        sort(x+1,x+1+n,cmp);sort(y+1,y+1+n,cmp);
        LL s1=0,s2=0;
        for(int i=1;i<=n;i++)s2+=x[i].v;
        for(int i=1;i<=n;i++){
            s2-=x[i].v;
            f1[x[i].id]=1ll*(i-1)*x[i].v-s1+s2-1ll*(n-i)*x[i].v;
            s1+=x[i].v;
        }
        s1=0,s2=0;
        for(int i=1;i<=n;i++)s2+=y[i].v;
        for(int i=1;i<=n;i++){
            s2-=y[i].v;
            f2[y[i].id]=1ll*(i-1)*y[i].v-s1+s2-1ll*(n-i)*y[i].v;
            s1+=y[i].v;
        }
        LL ans=1e18;
        for(int i=1;i<=n;i++)ans=min(ans,f1[i]+f2[i]);
        ans>>=1ll;
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    C++实现按1的个数排序
    杨绛100岁感言
    体验电影演员后的自白
    安装Leanote极客范的云笔记
    Linux下SonarQube代码质量平台的安装和使用方法
    前端开发利器VSCode
    苏州一日游 有惊无险!
    setuptools安装和错误解决
    Linux pip安装使用
    Linux平台安装MongoDB
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10481054.html
Copyright © 2011-2022 走看看