【u231】抗震救灾

来源:互联网 发布:cinema4dr18 mac 编辑:程序博客网 时间:2024/04/28 23:38

Time Limit: 1 second
Memory Limit: 128 MB

【问题描述】

这场灾难发生后,国家决定设立研究所研究灾后重建工作,由全国各地派技术人员来参加。因为每个地区所派的技术人员数目不
同,出于节约经费的问题,所以目前还没有决定到底有在哪个地区设置研究所进行研究。假设所有地区都在一条直线上,现在
只知道每个地区与汶川的距离和该地派出技术人员的数目(假设汶川在最左端)。请你编程帮助他们确定在哪个地区建立研究
所可以使所有技术人员集中到该地区的费用总和最小。

【输入格式】

输入文件每一行描述一个地区的信息(地区数<=5000)。 对于每一行,首先是该地区派出的技术人员数目,紧跟着是这个地区相对于汶川的距离,最后是该地区的名称。(技术人员数<=100,地区的相对距离<=10^31,地区名称长度<=20,数据保证有唯一的解);

【输出格式】

输出文件只需一行,即研究所设定的地区名称。

【数据规模】

Sample Input1

7 9289 shengyan
5 8523 beijing
3 5184 guilin
8 2213 chongqing
10 0 wuhan

Sample Output1

chongqing

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u231

【题解】

这类一个横轴上有多个低点;
每个点除了坐标之外还有一个权值;
然后让求使得∑w[i]*|x[i]-x[k]|最小的k
带权中位数问题;
本来如果权值为1;
(每个点都只有一个人)
->∑|x[i]-x[k]|;
现在权值不为1;
做法是累加前i个点的人数

∑(num[i])
找到第一个i
满足
∑(num[i])>=tot/2;
这里tot为num[1]+num[2]+..+num[n];
(其实这个东西对权值为1的也适用.把num都换成1就是了;)
然后所求的i就是最优解;

【完整代码】

#include <cstdio>#include <iostream>#include <vector>#include <algorithm>using namespace std;const int MAXN = 5e3+100;struct abc{    int num;    double dis;    string name;    friend bool operator < (abc a,abc b)    {        if (a.dis==b.dis)            return true;        else            return a.dis < b.dis;    }};abc a[MAXN];int n = 1,tot = 0;int main(){    //freopen("F:\\rush.txt","r",stdin);    while (cin >> a[n].num >> a[n].dis >> a[n].name) tot+=a[n].num,n++;    n--;    sort(a+1,a+1+n);    int sum = 0;    for (int i = 1;i <= n;i++)    {        sum+=a[i].num;        if (sum >= tot/2)        {            cout << a[i].name<<endl;            return 0;        }    }    return 0;}
0 0
原创粉丝点击