松鼠聚会

松鼠聚会

题意:网格图,有\(n\)个小松鼠,每个小松鼠到周围八个点的距离为\(1\),选定一个小松鼠的位置,是的所有松鼠到这个位置的最小路程和。

数据范围:

\(0 \le n \le 1e5 \,\, -10^9 \le x\le 10^9\)

解法:

题意中两个松鼠的最大距离即为切比雪夫距离:两个点横纵坐标之差的较大值

曼哈顿距离:两个点横纵坐标的差的绝对值之和

\(OI\)常用套路:

将一个点的坐标\((x,y)\)变为\((x + y, x - y)\) 后,原坐标系中的曼哈顿距离 = 新坐标系中的切比雪夫距离

反过来,将一个点的坐标\((x,y)\)变为\((\frac{x+y}{2},\frac{x-y}{2})\)后,原坐标系中的切比雪夫距离 = 新坐标系中的曼哈顿距离

这样我们就可以将原问题进行转化

不妨将转化后的\(x,y\)坐标进行排序,对一个点\(k\)答案就是统计\(x\)坐标:\(x[k]\times t-\sum_{i=1}^tx[i](x[t] < x[k]) +\sum_{i=k+1}^{n}x[i]- x[k]\times t\),统计\(y\)坐标同理

所以我们可以采用前缀和优化:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100100
#define ll long long
ll x1[maxn], y1[maxn];
ll x2[maxn], y2[maxn];
ll sumx[maxn], sumy[maxn];
int n;
int query1(ll x)
{
    int l = 1, r = n, ans = 0;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(x2[mid] <= x)
        {
            ans = mid;
            l = mid + 1;
        }
        else r = mid - 1;
    }
    return ans;
}
int query2(ll y)
{
    int l = 1, r = n, ans = 0;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(y2[mid] <= y)
        {
            ans = mid;
            l = mid + 1;
        }
        else r = mid - 1;
    }
    return ans;
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        x1[i] = x2[i] = x + y;
        y1[i] = y2[i] = x - y;
    }
    sort(x2 + 1, x2 + n + 1);
    sort(y2 + 1, y2 + n + 1);
    for(int i = 1; i <= n; i++)
    {
        sumx[i] = sumx[i - 1] + x2[i];
        sumy[i] = sumy[i - 1] + y2[i];
    }
    ll ans = 1e15;
    for(int i = 1; i <= n; i++)
    {
    	//printf("x1[%d] = %d y1[%d] = %d\n", i, x1[i], i, y1[i]);
        ll sum = 0;
        int x = query1(x1[i]), y = query2(y1[i]);
        sum += x * x2[x] - sumx[x] + sumx[n] - sumx[x - 1] - (n - x + 1) * x2[x];
        sum += y * y2[y] - sumy[y] + sumy[n] - sumy[y - 1] - (n - y + 1) * y2[y];
        ans = min(ans, sum);
    }
    printf("%lld\n", ans >> 1);
    return 0;
}
posted @ 2019-10-16 13:50  Akaina  阅读(149)  评论(0编辑  收藏  举报