Bzoj3170: [Tjoi2013]松鼠聚会 (切比雪夫距离)

题目链接
显然,题目要求我们求切比雪夫距离,不会的可以去看一下attack的博客。
考虑枚举所有的点
转换为曼哈顿距离后.
那么对于这个点的路程和是。

\[\sum_{i=1}^n | x_i - x_k| + |y_i - y_k| \]

考虑是绝对值.
将横纵坐标\(sort\)一下,\(lower_bound\)查询即可
接下来就简单多了
分情况讨论即可.
然后我只是化简了一下式子.
需要注意的是.由于转化为曼哈顿距离除以二时会有精度问题,所以这里先不除以二,最后的答案才除以二.

#include <iostream>
#include <algorithm>
#include <cstdio>
#define ll long long
const int maxN = 100000 + 7;
using namespace std;

ll x[maxN],y[maxN],n;
ll std_x[maxN],std_y[maxN];
ll sum_x[maxN],sum_y[maxN];

void Sub2() {
    ll ans = 1e18;
    for(int i = 1;i <= n;++ i) {
        x[i] = std_x[i];
        y[i] = std_y[i];
    }
    sort(x + 1,x + n + 1);
    sort(y + 1,y + n + 1);
    for(int i = 1;i <= n;++ i) sum_x[i] = sum_x[i - 1] + x[i];
    for(int i = 1;i <= n;++ i) sum_y[i] = sum_y[i - 1] + y[i];
    for(int i = 1;i <= n;++ i) {
        ll sum = 0;
        ll pos_x = lower_bound(x + 1,x + n + 1,std_x[i]) - x;
        ll pos_y = lower_bound(y + 1,y + n + 1,std_y[i]) - y;
        sum = (2 * pos_x - n) * x[pos_x] - 2 * sum_x[pos_x] + sum_x[n] +
              (2 * pos_y - n) *	y[pos_y] - 2 * sum_y[pos_y] + sum_y[n];
        ans = min(ans,sum);
    }
    printf("%lld", ans / 2);
    return ;
}

int main() {
    scanf("%lld",&n);
    ll g,z;
    for(int i = 1;i <= n;++ i) {
        scanf("%lld%lld",&g,&z);
        std_x[i] = g + z;
        std_y[i] = g - z;
    }	
    Sub2();
    return 0;
}
posted @ 2018-09-25 20:31  Rlif  阅读(127)  评论(0编辑  收藏  举报