Tower /点的移动(洛谷 1632)题解

来源:互联网 发布:知乎 国家开发投资集团 编辑:程序博客网 时间:2024/06/08 09:21
【问题描述】

    平面上有N个整数坐标点。如果将点(x0,y0)移动到(x1,y1),则需要的代价为|x0-x1|+|y0-y1|。求使得K(K=1,…,N)个点在同一位置上最少需要的代价。

【样例输入】

    4 
    15 14
    15 16
    14 15
    16 15

【样例输出】 

    0
    2
    3
    4

【解题思路】

    初看这道题,还以为是只能移动到有点的地方,即把别的点移动到一个点上,移动(k-1)个点所需要的最小代价,结果发现样例都过不去……接着分析了一下样例,发现样例是将k个点都移动到了(15,15)上去,当然,k=1的时候不需要移动,于是我就去找所有x,y的中位数,结果过了样例,但是OJ上为0分,那我们再重新来分析一下题目。

    题目中是可以移到任意一个点的,我们不难发现这个点的x必定在所有x坐标之间,同理,y也如此,因此,我们只要枚举每一个x,y然后将每一个点都去移动一次,找出移动k个点的时候,最小的移动代价即可。

    那么我们在这题中可以用一个三重循环,因为N的值并不大,只有50,三重循环并不会TLE。这里用三重循环的作用是方便计算每一个点移动的代价,详见代码。

【代码实现】

 1 type rec=record   2      x,y:longint;   3 end;   4 var a:array[0..55] of rec;   5     f:array[0..55,0..55] of longint;   6     d,ans:array[0..55] of longint;   7     i,j,n,k,s:longint;   8 procedure sort(l,r:longint);   9 var i,j,x,y:longint;  10 begin  11  i:=l;  12  j:=r;  13  x:=d[(l+r) shr 1];  14  repeat  15   while d[i]<x do  16    inc(i);  17   while x<d[j] do  18    dec(j);  19   if not(i>j) then  20    begin  21     y:=d[i];  22     d[i]:=d[j];  23     d[j]:=y;  24     inc(i);  25     j:=j-1;  26    end;  27  until i>j;  28  if l<j then  29   sort(l,j);  30  if i<r then  31   sort(i,r);  32 end;  33 begin  34  readln(n);  35  for i:=1 to n do  36   with a[i] do  37    readln(x,y);  38  for i:=1 to n do  39   ans[i]:=maxlongint;  40  for i:=1 to n do  41   for j:=1 to n do  42    begin  43     for k:=1 to n do  44      d[k]:=abs(a[k].x-a[i].x)+abs(a[k].y-a[j].y);  //枚举每一个点移动到xi,yj上需要的代价。45     sort(1,n);  46     s:=0;  47     for k:=1 to n do  48      begin  49       s:=s+d[k];  50       if s<ans[k] then  51        ans[k]:=s;  52      end;  //更新最优解53    end;  54  for i:=1 to n do  55   writeln(ans[i]);  56 end.  

 

0 0
原创粉丝点击