基准时间限制:1 秒 空间限制:131072 KB 分值: 40
难度:4级算法题
X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i]。该点到其他点的带权距离 = 实际距离 * 权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。
Input
第1行:点的数量N。(2 <= N <= 10000) 第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值。(-10^5 <= X[i] <= 10^5,1 <= W[i] <= 10^5)
Output
输出最小的带权距离之和。
Input示例
5 -1 1 -3 1 0 1 7 1 9 1
Output示例
20
所有空间里的最小距离都可以转化为中位数来计算
这里的一个小技巧:将一个点权值w[i]看做有w[i]个这样的点
即转化为以为坐标来计算。
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<limits.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<math.h>
#include<string>
#include<map>
using namespace std;
#define maxn 100005
typedef long long ll;
struct node
{
ll x,y;
}a[maxn];
bool comp(node a,node b)
{
if(a.x<b.x)return 1;
return 0;
}
int main()
{
ll n,m=0,i,sum=0;
ll ans=0;
scanf("%lld",&n);
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&a[i].x,&a[i].y);
sum+=a[i].y;
}
ll temp=a[1].x;
sum/=2;
sort(a+1,a+n+1,comp);
for(i=1;i<=n;i++)
{
m+=a[i].y;
if(m>sum)
{
temp=a[i].x;
break;
}
}
for(i=1;i<=n;i++)
ans+=abs(a[i].x-temp)*a[i].y;
printf("%lld\n",ans);
}