【带权中位数】【120715测试】【朱全明NOIP模拟题】YL杯超级篮球赛
样例输入输出
ball.in
1
1
0 0
ball.out
0.00
这是一道有关带权中位数(http://www.cnblogs.com/oijzh/articles/2647134.html)的题
分析题目不难发现,xy坐标是不相关的,所以应该离散化分开来,并且最终的目标位置必定在某一个人的点上(如果不在某一个点上,那么必定可以把这个点向左或向右移来找到一个更优的位置!)
了解了带权中位数,这道题就很好做了
Pascal Code
program ball; type arr=array[0..500000+10] of longint; var n,total:longint; w,oldw,x,y:arr; procedure init; begin assign(input,'ball.in'); assign(output,'ball.out'); reset(input); rewrite(output); end; procedure outit; begin close(input); close(output); halt; end; procedure readdata; var i:longint; begin read(n); for i:=1 to n do begin read(w[i]); inc(total,w[i]); end; for i:=1 to n do read(x[i],y[i]); end; procedure swap(var a,b:longint); var t:longint; begin t:=a;a:=b;b:=t; end; procedure qs(var a:arr;l,r:longint); var i,j,x:longint; begin i:=l;j:=r;x:=a[i+(j-i)div 2]; repeat while a[i]<x do inc(i); while a[j]>x do dec(j); if i<=j then begin swap(a[i],a[j]); swap(w[i],w[j]); inc(i);dec(j); end; until i>j; if i<r then qs(a,i,r); if l<j then qs(a,l,j); end; function workx:double; var i,tx:longint; sum:double; begin sum:=0; for i:=1 to n do begin sum:=sum+w[i]; if sum>total/2 then begin tx:=x[i]; break; end; end; sum:=0; for i:=1 to n do begin if x[i]=tx then continue; sum:=sum+w[i]*abs(x[i]-tx); end; exit(sum); end; function worky:double; var i,ty:longint; sum:double; begin sum:=0; for i:=1 to n do begin sum:=sum+w[i]; if sum>total/2 then begin ty:=y[i]; break; end; end; sum:=0; for i:=1 to n do begin if y[i]=ty then continue; sum:=sum+w[i]*abs(y[i]-ty); end; exit(sum); end; procedure main; var xx,yy:double; begin oldw:=w; qs(x,1,n); xx:=workx; w:=oldw;//这个一定不能忘了 因为前面排序x的时候已经打乱了w的值!!! qs(y,1,n); yy:=worky; writeln(xx+yy:0:2); end; begin init; readdata; main; outit; end.
..... 转载请注明出处 ..... http://oijzh.cnblogs.com ..... by jiangzh