YL杯超级篮球赛_纪中_1325
题目大意
一年一度的高一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].w<mid do i:=i+1; while a[j].w>mid 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.