zoukankan      html  css  js  c++  java
  • Tower /点的移动(洛谷 1632)题解

    【问题描述】

        平面上有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.  
  • 相关阅读:
    markdown图片设置
    编程变量名
    c++ 子类构造函数初始化及父类构造初始化
    idea中解决Git反复输入代码的问题
    idea中修改git提交代码的用户名
    网络相关
    idea Controller层编译Mapper层报错
    java7与java8的新特性
    修改列名以及其数据类型
    修改数据库表的某个字段默认值
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4553817.html
Copyright © 2011-2022 走看看