带权中位数liuseroj.picp.io

题目描述
位于一条笔直的公路的一边上有 N村庄用一条数轴来描述这条公路,每个村庄都有一个整数坐标 x 和该村庄的人数 p。两个村庄的距离定义为他们坐标差的绝对值。现在需要在某个村庄里修建一个邮局,那么这个邮局应修建在那个村庄才能使得各村庄到邮局的距离总和最小。

输入格式
第一行是一个整数n,表示村庄数量。接下来的 n行,每行包含两个整数 x[i],p[i],表示第 i个村庄的坐标和该村庄的人数。

输出格式
所有人到邮局的距离总和的最小值。

样例
样例输入
5
7 6
1 3
10 5
6 2
3 7
样例输出
62
数据范围与提示
1<n<30000
0<x[i]<100000
0<p[i]<100

#include <bits/stdc++.h>
using namespace std;
// tupedef pair<int,int> p;
struct p {
    int first, second;
};
int main() {
    freopen("B.in", "r", stdin);
    freopen("B.out", "w", stdout);
    p v[30000];
    long long n, sum = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> v[i].first >> v[i].second;
        sum += v[i].second;
    }
    sort(v, v + n, [](p a, p b) { return a.first < b.first; });
    int left = 0;
    int idx = 0;
    while (2 * left < sum) {
        left += v[idx].second;
        idx++;
    }
    idx--;
    sum = 0;
    for (int i = 0; i < n; i++) {
        sum += abs(v[idx].first - v[i].first) * v[i].second;
    }
    cout << sum;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值