题目大意
一年一度的高一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 )的选择。
因为参赛人数众多,所以小三希望你能编写一个程序,即帮他找出某个时刻的最佳攻击点。
分析
看了题解,是带权中位数,但不懂。
代码
type
arr=record
x,w:longint;
end;
arry=array[1..60000] of arr;
var
x,y:arry;
i,j,k:longint;
n:longint;
max:longint;
procedure qsort(var a:arry; l,r:longint);
var
i,j,k:longint;
mid:longint;
temp:arr;
begin
if l>=r then exit;
i:=l; j:=r;
mid:=a[(l+r) div 2].w;
repeat
while a[i].wmid do j:=j-1;
if i<=j
then
begin
temp:=a[i]; a[i]:=a[j]; a[j]:=temp;
i:=i+1; j:=j-1;
end;
until i>j;
qsort(a,l,j);
qsort(a,i,r);
end;
procedure init;
var
i,j,k:longint;
begin
readln(n);
max:=0;
for i:=1 to n do
begin
read(x[i].x);
y[i].x:=x[i].x;
max:=max+y[i].x;
end;
for i:=1 to n do
readln(x[i].w,y[i].w);
end;
procedure main;
var
i,j,k:longint;
jj:longint;
ans:real;
begin
qsort(x,1,n);
jj:=0; j:=0;
for i:=1 to n do
begin
jj:=jj+x[i].x;
if jj>max/2
then
begin
j:=i;
break;
end;
end;
ans:=0;
for i:=1 to n do
begin
if i=j then continue;
ans:=ans+x[i].x*abs(x[i].w-x[j].w);
end;
qsort(y,1,n);
jj:=0; j:=0;
for i:=1 to n do
begin
jj:=jj+y[i].x;
if jj>max/2
then
begin
j:=i;
break;
end;
end;
for i:=1 to n do
begin
if i=j then continue;
ans:=ans+y[i].x*abs(y[i].w-y[j].w);
end;
write(ans:0:2);
end;
begin
init;
main;
end.