【带权中位数】安装服务器

安装服务器

(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.


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值