YL杯超级篮球赛

来源:互联网 发布:苹果id解锁软件 编辑:程序博客网 时间:2024/06/02 17:11

YL杯超级篮球赛

Time Limits: 1000 ms Memory Limits: 65536 KB

Description
  一年一度的高一YL杯超级篮球赛开赛了。当然,所谓超级,意思是参赛人数可能多余5人。小三对这项篮球非常感兴趣,所以一场都没有落下。每个中午都准时守侯在篮球场看比赛。经过一个星期的研究,小三终于对篮球的技战术找到了一丝丝感觉了。他发现打YL杯的每个班都有一套相似的进攻战术:
  1 :控球后卫带球到前场,找到一个最佳攻击点 ( x , y )
  2 :所有除控卫以外的队员都从各自的当前位置迅速向 ( x , y ) 移动
  3 :控球后卫根据场上情况组织进攻
  这个战术对于一般情况是非常奏效的,但是每个队员毕竟不像小三一样每天精力过剩,每个队员都有一个疲劳指数W,显然对于每个队员的移动需要消耗一些能量。
  假设一个队员从位置 ( x1 , y1 ) 移动到 ( x , y )的能量消耗为 w * (ABS ( x - x1 ) +ABS ( y - y1 ) ), 这里ABS为绝对值函数。那么我们希望整个队伍一次进攻的能量消耗当然是越少越好。显然能量消耗的多少直接取决于控球后卫对于攻击点 ( x , y )的选择。
  因为参赛人数众多,所以小三希望你能编写一个程序,即帮他找出某个时刻的最佳攻击点。

Input
  第一行:一个整数N,表示篮球队人数
  第二行:一共N个整数,其中的第i个数Wi表示第i个队员的疲劳指数。
  第3~N+2行:每一行两个整数X和Y,其中的第i+2行,表示第i个队员的当前位置的横坐标和纵坐标。

Output
  一个实数。表示所有队员集合到最佳攻击位置的能量消耗总和,答案保留两位小数。

Sample Input

110 0

Sample Output

0.00

题目大意

这道题上前面有一大串都是没用的。主干的意思大致是,题目给了你n个点,每个点都有一个常数Wi,和它的坐标(Ai,Bi)。

目前定义一个带有常数V点(X1,Y1)到一个坐标为(X2,Y2)的位置花费为
F(X1,Y1)=V(|X1X2|+|Y1Y2|)

那么,让你求一个位置(x,y),让所有点都走到这个位置,得到一个总的花费,求所有总的花费的最小值


解题思路

因为他求的点与点的距离并不是勾股定理,所以,这道题就变得简单了许多,点与点的距离,只跟横坐标与纵坐标的差距有关系,所以我们就可以将点的横坐标和纵坐标分开来讨论。

就拿横坐标来说,倘若所有的常数都为1,是不用想的太多的。
点数为奇数的情况,倘若每个点所在横坐标的位置如下:
a–>b–>c–>d–>e

你选取的位置的横坐标为x,将x从a移动到e会发现,
a–>b段上x与a拉开一个ab的距离,和bcde缩小了ab的距离,也就是缩小了3个ab,答案在减少
b–>c段上x与ab拉开一个bc的距离,和cde缩小了bc的距离,也就是缩小了1个bc,答案在减少
c–>d段上x与abc拉开一个cd的距离,和de缩小了cd的距离,也就是增加了1个cd,答案在增加
d–>e段上x与abcd拉开一个de的距离,和e缩小了de的距离,也就是增加了3个de,答案在增加

可以得出x在c的位置上是最优解

点数为偶数的情况,倘若每个点所在横坐标的位置如下:
a–>b–>c–>d–>e–>f

你选取的位置的横坐标为x,将x从a移动到e会发现,
a–>b段上x与a拉开一个ab的距离,和bcdef缩小了ab的距离,也就是缩小了4个ab,答案在减少
b–>c段上x与ab拉开一个bc的距离,和cdef缩小了bc的距离,也就是缩小了2个bc,答案在减少
c–>d段上x与abc拉开一个cd的距离,和def缩小了cd的距离,也就是不变
d–>e段上x与abcd拉开一个de的距离,和ef缩小了de的距离,也就是增加了3个de,答案在增加
e–>f段上x与abcde拉开一个ef的距离,和f缩小了ef的距离,也就是增加了3个ef,答案在增加

可以得出x在c-d的位置上是最优解

综上所述,我们可以发现,当所有常数都为一时,取中位数即可。但常数不为一怎么办?那就将常数为v的点看作v个这样的点,答案不影响。

求纵坐标的同理。

Codes:

#include<cstdio>#include<cmath>#include<cstring>#define fo(i,x,y) for(int i=x;i<=y;i++)using namespace std;struct Point{    int x,y,t;  }a[50001];int n,tot=0,ansx,ansy;double ans=0.0;int getx();int gety();void q(int,int);void p(int,int);int main(){    scanf("%d",&n);    fo(i,1,n){scanf("%d",&a[i].t);tot+=a[i].t;}    fo(i,1,n)scanf("%d%d",&a[i].x,&a[i].y);    ansx=getx();ansy=gety();    fo(i,1,n)ans+=(abs(ansx-a[i].x)+abs(ansy-a[i].y))*a[i].t;    printf("%.2lf",ans);}int gety(){    p(1,n);    int total=0;    fo(i,1,n)    {        total+=a[i].t;        if(total>=(tot+1)>>1)return(a[i].y);    }}int getx(){    q(1,n);    int total=0;    fo(i,1,n)    {        total+=a[i].t;        if(total>=(tot+1)>>1)return(a[i].x);    }}void q(int h,int t){    int l=h,r=t,m=a[(h+t)>>1].x;    do    {        while(a[l].x<m)l++;        while(a[r].x>m)r--;        if(l<=r)        {            a[0]=a[l];a[l]=a[r];a[r]=a[0];            l++;r--;        }    }while(!(l>r));    if(h<r)q(h,r);if(l<t)q(l,t);}void p(int h,int t){    int l=h,r=t,m=a[(h+t)>>1].y;    do    {        while(a[l].y<m)l++;        while(a[r].y>m)r--;        if(l<=r)        {            a[0]=a[l];a[l]=a[r];a[r]=a[0];            l++;r--;        }    }while(!(l>r));    if(h<r)p(h,r);if(l<t)p(l,t);}
0 0
原创粉丝点击