集训4.10-篮球赛

来源:互联网 发布:linux执行sql文件 编辑:程序博客网 时间:2024/04/23 19:04

篮球赛

题目描述

一年一度的高一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 )的选择。 因为参赛人数众多,所以小三希望你能编写一个程序,即帮他找出某个时刻的最佳攻击点。

输入格式 

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

输出格式 

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

做法1:求中位数。当一条数轴上有n个点时,让他们都到一个点,求最短距离。例如说有三个点,坐标分别为,2,4,6。设让他们到的点坐标为x,当x<2时,所有人都走了很远的一段距离,显然不是最优的。,那么就将x慢慢增大,往2靠近,直到到第一个点,那么这个时候如果x走1,那么第一个点会多走1,但是后面两个点少走1,比原来更优。一直到到了第二个店。如果x再增大,那么会有两个点走多1,一个点少走1,显然方案没有之前的好。所以最优就是第二个点上。例子的n是奇数的,偶数也同理,但是结果不一样,当n为奇数时,在第a[n/2+1]最优,当n为偶数时,在[a[n/2],a[n/2+1]](a表示坐标)。

二维的中位数也同理,把x轴和y轴分别做一遍,x轴的中位数和y轴的中位数就是二维的中位数。

题目多了一个w,是一个带权的中位数,也可以用以上方法做,权的方面用个前缀和就能过。

时间复杂度:O(10^6)期望得分100。

做法2:这个做法也要用到中位数。我们可以把权为wi的一个点分成wi个权为1的点。然后就把问题化成了一个不带权求中位数的问题,按照上面的方法就可以直接求了。

时间复杂度:O(n)期望得分100.

方法二code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define Maxn 50020
using namespace std;
struct data{
long long x,y;
long long w;
};
bool cmpx(data t,data k)
{
return t.x<k.x;
}
bool cmpy(data t,data k)
{
return t.y<k.y;
}
int n;
data a[Maxn];
long long fa,fb;
long long so=0;
long long kk=0;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i].w);
for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmpx);
for(int i=1;i<=n;i++)kk+=a[i].w;
for(int i=1;i<=n;i++)
{
so+=a[i].w;
if(so>=kk/2+1)
{
fa=a[i].x;
break;
}
}
so=0;
sort(a+1,a+n+1,cmpy);
for(int i=1;i<=n;i++)
{
so+=a[i].w;
if(so>=kk/2+1)
{
fb=a[i].y;
break;
}
}
long long ans=0LL;
for(int i=1;i<=n;i++)
ans+=a[i].w*(abs(a[i].x-fa)+abs(a[i].y-fb));
printf("%lld.00",ans);
return 0;
}


0 0
原创粉丝点击