• 【bzoj3170】[Tjoi2013]松鼠聚会


    3170: [Tjoi2013]松鼠聚会

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1670  Solved: 885
    [Submit][Status][Discuss]

    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

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

    Sample Input

    6
    -4 -1
    -1 -2
    2 -4
    0 2
    0 3
    5 -2

    Sample Output

    20

    HINT

     

    Source

     
    [Submit][Status][Discuss]
     
    题意:N个点,求某一个点到其他点的切比雪夫距离之和最小化;
    题解:
            推荐一篇页面比较好讲得很清楚的博客:https://www.cnblogs.com/zwfymqz/p/8253530.html
            两个点(x1,y1) 和 (x2,y2)
            切比雪夫距离:max(|x1-x2|,|y1-y2|)
            曼哈顿距离:|x1-x2|+|y1-y2|
            先介绍绝对值的两个性质:|a|+|b| = max(|a+b|,|a-b|)  max(|a|,|b|) = |(a+b)/2|+|(a-b)/2|
            可以利用数轴理解一下;
            利用上面的性质可以知道:
            若:(x,y) – > (x-y,x+y) 则新图的切比雪夫距离为原图的曼哈顿距离;
            若:(x,y) – > ((x-y)/2,(x+y)/2) 则新图的曼哈顿距离为原图的切比雪夫距离;
            为什么要转化呢?
            切比雪夫不好处理,转化后对曼哈顿距离分x,y排序,预处理某个值到前面的曼哈顿距离之和,可以做到O(1)查询,此题直接枚举哪个点;
            另外如果最近的点不要求在这些点里面而是平面的任何一个点,分别贪心选取x坐标,y坐标的排序后的中位数,注意切比雪夫转曼哈顿,有可能不是整点,要求整点还需要特判一下;
     
     1  
     2 #include<cstdio>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<queue>
     7 #include<cmath>
     8 #include<vector>
     9 #include<stack>
    10 #include<map>
    11 #define Run(i,l,r) for(int i=l;i<=r;i++)
    12 #define Don(i,l,r) for(int i=l;i>=r;i--)
    13 #define ll long long
    14 #define inf 0x3f3f3f3f
    15 using namespace std;
    16 const int N=100010;
    17 int n,px[N],py[N];
    18 ll upx[N],dnx[N],upy[N],dny[N];
    19 struct data{
    20     int x,id;
    21     bool operator <(const data&A)const{
    22         return x<A.x;
    23     }
    24 }X[N],Y[N];
    25 int main(){
    26 //  freopen("bzoj3170.in","r",stdin);
    27 //  freopen("bzoj3170.out","w",stdout);
    28     scanf("%d",&n);
    29     for(int i=1;i<=n;i++){
    30         int a,b;
    31         scanf("%d%d",&a,&b);
    32         X[i]=(data){a-b,i};
    33         Y[i]=(data){a+b,i};
    34     }
    35     sort(X+1,X+n+1);
    36     sort(Y+1,Y+n+1); 
    37     for(int i=1;i<=n;i++){
    38         px[X[i].id]=i;
    39         py[Y[i].id]=i;      
    40     } 
    41     ll ans=1e18;
    42     for(int i=1;i<=n;i++){
    43         upx[i]=upx[i-1]+1ll*(i-1)*(X[i].x-X[i-1].x);
    44         upy[i]=upy[i-1]+1ll*(i-1)*(Y[i].x-Y[i-1].x);
    45     }
    46     for(int i=n;i;i--){
    47         dnx[i]=dnx[i+1]+1ll*(n-i)*(X[i+1].x-X[i].x);
    48         dny[i]=dny[i+1]+1ll*(n-i)*(Y[i+1].x-Y[i].x);
    49     }
    50     for(int i=1;i<=n;i++){
    51         ans=min(ans,upx[px[i]]+dnx[px[i]]+upy[py[i]]+dny[py[i]]);
    52     }
    53     printf("%lld
    ",ans>>1);
    54     return 0;
    55 }//by tkys_Austin;
    View Code
     
  • 相关阅读:
    ES6学习--函数剩余参数 (rest参数)
    ES6学习 --函数参数默认值与解构赋值默认值
    ES6学习--Array.from()方法
    02ython基础知识(一)
    01 Python初探
    c#利用IronPython调用python的过程种种问题
    Android 对话框(Dialogs)
    不可不知的安卓屏幕知识
    C#中的Split用法以及详解
    关于XML文档操作类
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/9814343.html
Copyright © 2020-2023  润新知