hjyzoj#3. 松鼠聚会

本文介绍了一段C++代码,用于解决计算给定二维点集合中每个点的曼哈顿距离,并通过前缀和和二分查找优化求解所有点的总和问题。
摘要由CSDN通过智能技术生成

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

template <class T>
inline void read(T &x) {
    x = 0;
    char c = getchar();
    bool f = 0;
    for (; !isdigit(c); c = getchar()) f ^= c == '-';
    for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    x = f ? -x : x;
}

template <class T>
inline void write(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    T y = 1;
    int len = 1;
    for (; y <= x / 10; y *= 10) ++len;
    for (; len; --len, x %= y, y /= 10) putchar(x / y + 48);
}

const int MAXN = 1e5;
int n, x[MAXN + 5], y[MAXN + 5], p[MAXN + 5], q[MAXN + 5];
LL ans = 0x7fffffffffffffff, prex[MAXN + 5], prey[MAXN + 5];

int main() {
    read(n);
    for (int a, b, i = 1; i <= n; ++i) {
        read(a), read(b);
        x[i] = p[i] = a + b, y[i] = q[i] = a - b;//转曼哈顿距离,且乘上 2 
    }
    sort(p + 1, p + n + 1), sort(q + 1, q + n + 1);//排序 
    for (int a, b, i = 1; i <= n; ++i)//维护前缀和 
        prex[i] = prex[i - 1] + p[i], prey[i] = prey[i - 1] + q[i];
    for (int posx, posy, i = 1; i <= n; ++i) {
        posx = lower_bound(p + 1, p + n + 1, x[i]) - p;
        posy = lower_bound(q + 1, q + n + 1, y[i]) - q;
        //二分找到 x[i] 和 y[i] 是所有点中第几个大的 
        LL sumx, sumy;
        sumx = (LL) posx * x[i] - prex[posx] + 
        prex[n] - prex[posx] - (LL) (n - posx) * x[i];//计算横坐标贡献 
        sumy = (LL) posy * y[i] - prey[posy] + 
        prey[n] - prey[posy] - (LL) (n - posy) * y[i];//计算纵坐标贡献 
        ans = min(ans, sumx + sumy);
    }
    write(ans / 2);//答案不要忘记除回去 
    putchar('\n');
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值