SGU114 Telecasting Station
题目大意:
百慕大的每一座城市都坐落在一维直线上。这个国家的政府决定建造一个新的广播电视台。经过了许多次试验后,百慕大的科学家们提出了一个结论,在每座城市的不满意度等于这座城市的市民数与这座城市与广播电视台的距离的乘积。找到这个一维直线上的一点来建造广播电视台,使得所有城市的不满意度的和最小。
输入格式
输入的第一行是一个正整数N(0<N<15000) 表示百慕大的城市数。下面N个点对 (X, P) 表示城市 (0<X, P<50000), X 是这座城市的坐标(整数),P是市民数。所有的数都用一个空格分隔开。
输出格式
输出最好的电视台的位置,精确到10^(-5)
样例输入
4
1 3
2 1
5 2
6 2
样例输出
3.00000
数学题一道(水题吧)
首先,答案在不在整点上是没有影响的(所以说.00000是坑爹的)
思考:当左边的点数和右边的点数的个数差最小时,答案最小。
证明:设当前点x的左边有lx个点,右边有rx个点。
将x向左平移k个单位,总不满度ans变成ans-lx*k+rx*k=ans-(lx-rx)*k;
将x向右平移k个单位,总不满度ans变成ans-rx*k+lx*k=ans-(rx-lx)*k;
如果lx>rx则x可以向左移,如果rx>lx则x可以向右移。
不过事实上lx并不一定能等于rx(因为每个点答案不同),所以我们只需让x的左边尽量包含一般的点(中部思想)
下面附上我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#define ABS(a) ((a)>=(0)?(a):(-a))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
int city[50001];
int n,ans,max,sum,min=2147483647,absmin=2147483647;
void init()
{
int i,k,x,l,r;
int ansmid,mid;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d%d",&k,&x);
max=MAX(k,max);
min=MIN(k,min);
city[k]+=x;
sum+=x;
}
sum/=2;
for (i=min;i<=max;i++)
{
city[i]+=city[i-1];
if (city[i]>=sum)
break;
}
printf("%d.00000",i);
return ;
}
int main()
{
init();
return 0;
}