zoukankan      html  css  js  c++  java
  • Bzoj 3170[Tjoi 2013]松鼠聚会 曼哈顿距离与切比雪夫距离

    3170: [Tjoi 2013]松鼠聚会

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1318  Solved: 664
    [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
      这道题貌似纯考小知识点吧……
      不得不说做这道题挺长姿势的,科普一下:欧几里德距离,曼哈顿距离,切比雪夫距离(在这里博主不介绍在数学其他方面的定义,用途)。
        欧几里德距离: 两点间的直线距离。(sqrt((x1-x2)^2+(y1-y2)^2)
        曼哈顿距离(出租车几何):两个点在标准坐标系上的绝对轴距总和。(|x1-x2|+|y1-y2|)。
        切比雪夫距离(棋盘距离):在国际象棋中国王到其他点的距离。(max(|x1-x2|,|y1-y2|))。
      这三个距离各有各的用处,这道题主要涉及的是曼哈顿距离和切比雪夫距离的转化。
      首先先明确一点,松鼠家之间的距离是切比雪夫距离,即我们先斜着走,在横着或竖着走,显而易见是最快的。
      但是,这样我们只能写出n^2打法,过这道题还是不太可能。因此,我们需要一个神奇的东西:切比雪夫距离转曼哈顿距离。
        设两个点为(x1,y1)(x2,y2)把两个点换成(x1+y1,x1-y1)(x2+y2,x2-y2)他们的曼哈顿距离除二就是(x1,y1)(x2,y2)的切比雪夫距离。
      剩下的,我们利用前缀和就可以做到了。
      至于证明,网上很多。
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <string>
     6 #include <queue>
     7 #include <algorithm>
     8 #include <cmath>
     9 #include <map>
    10 #define N 100005
    11 using namespace std;
    12 int n;
    13 struct no
    14 {
    15     long long x,y,bh;
    16 }node[N];
    17 long long ans[N],sumx[N],sumy[N];
    18 bool px1(no a,no b)
    19 {
    20     if(a.x==b.x)return a.y<b.y;
    21     return a.x<b.x;  
    22 }
    23 bool px2(no a,no b)
    24 {
    25     if(a.y==b.y)return a.x<b.x;
    26     return a.y<b.y;
    27 }
    28 int main()
    29 {
    30     scanf("%d",&n);
    31     for(int i=1;i<=n;i++)
    32     {
    33         int x,y;
    34         scanf("%d%d",&x,&y);
    35         node[i].x=x+y,node[i].y=x-y;
    36         node[i].bh=i;
    37     }
    38     sort(node+1,node+1+n,px1);
    39     for(int i=1;i<=n;i++) sumx[i]=node[i].x+sumx[i-1];
    40  
    41     for(long long i=1;i<=n;i++)
    42     {   
    43         ans[node[i].bh]+=i*node[i].x-sumx[i]+sumx[n]-sumx[i]-(n-i)*node[i].x;
    44     }
    45     sort(node+1,node+1+n,px2);
    46     for(int i=1;i<=n;i++)sumy[i]=node[i].y+sumy[i-1];
    47     for(long long i=1;i<=n;i++)
    48     {
    49         ans[node[i].bh]+=i*node[i].y-sumy[i]+sumy[n]-sumy[i]-(n-i)*node[i].y;
    50          
    51     }
    52          
    53     long long an=1000000000ll*1000000000ll;
    54     for(int i=1;i<=n;i++)
    55     {
    56         if(ans[i]/2<an)an=ans[i]/2;
    57     }
    58     printf("%lld
    ",an);
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    AngularJS各种'service'的区别
    js 斐波那契数列实现
    Mac下Apache+MySQL+PHP开发环境安装过程
    原生封装的js前端工具库(包含了jquery的常用功能)
    BFC 神奇背后的原理
    CSS清浮动处理(Clear与BFC)
    JavaScript实现 页面滚动图片加载(懒加载)
    CodeForce 814B
    排序算法
    uva1610
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7674200.html
Copyright © 2011-2022 走看看