安装服务器
(server.pas/c/cpp)
【问题描述】
*计划建立一个大型的服务器中心,为各个城市提供网络服务。每个城市对网络的需求量是不一样的,而需求量越大,对线路的要求也就越高,线路的成本也就越高。因此需要选择合适的地点修建。每个城市用一个二维整数坐标表示,两个点之间的距离定义为水平距离+垂直距离,即a,b两点间距离为D(a,b)=|Xa-Xb|+|Ya-Yb|。对于每个城市,线路的费用为:费用=距离×人口×城市的网络需求程度。总的费用为各个城市的费用的总和。请你找出最适合安装服务器(既总费用最小)的整数坐标(不一定要在城市上)。
【输入文件】
输入文件server.in第一行有一个正整数N(N ≤ 100000),表示城市的数量。后面的n行每行描述一个城市,每行有四个整数x,y,p,k分别表示城市的坐标,人口数,以及网络需求程度。(0 < x, y < 2^31;p≤600, k ≤30)
【输出文件】
输出文件server.out包含一行。在这一行中,应当包含两个整数x,y表示最优解的坐标,如果有多个最优解,那么输出x最小的,如果有x相同,那么输出y最小的。
【样例输入】
5
2 3 5 3
2 1 100 30
2 2 1 1
3 2 7 6
1 1 4 30
【样例输出】
2 1
【数据规模】
对于30%的数据,保证有N <= 500,x, y <= 100;
对于50%的数据,保证有N <= 5000;
对于全部的数据,保证有N <= 100000。
前面那个 YL杯篮球赛http://www.cnblogs.com/oijzh/archive/2012/08/20/2647125.html 已经做过这个带全中位数的题目了,而且这一题更加简单,只用找出那一个点即可
Pascal Code
program server; type arr=array[0..100000+10] of longint; var n:longint; total:double; x,y,v,oldv:arr; procedure init; begin assign(input,'server.in'); assign(output,'server.out'); reset(input); rewrite(output); end; procedure outit; begin close(input); close(output); halt; end; procedure readdata; var i,p,k:longint; begin read(n); for i:=1 to n do begin read(x[i],y[i],p,k); v[i]:=p*k; total:=total+v[i]; end; 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(v[i],v[j]);//忘打了。。。居然还有20分。。。 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:longint; var i:longint; sum:double; begin sum:=0; for i:=1 to n do begin sum:=sum+v[i]; if sum>total/2 then begin exit(x[i]); end; end; end; function worky:longint; var i:longint; sum:double; begin sum:=0; for i:=1 to n do begin sum:=sum+v[i]; if sum>total/2 then begin exit(y[i]); end; end; end; procedure main; var tx,ty:longint; begin oldv:=v; qs(x,1,n); tx:=workx; v:=oldv; qs(y,1,n); ty:=worky; writeln(tx,' ',ty); end; begin init; readdata; main; outit; end.