• 曼哈顿距离转化


    驶员们(drivers)
    【问题描述】
    第32次移民计划的母舰阿姆斯特朗号,满载着无家可归的人们,在太空中飘荡,寻找安身的角落。在他们找到自己的归宿之前,他们的母星斥巨资建造的母舰拥有人造太阳和大气,土地、房屋和足够的设施,足够他们的生活很长一段时间了。 
    守护着母舰安全的护卫队是一支庞大的军队,勇敢的士兵要负责保护母舰免于太空中的各种侵扰,比如陨石,以及可能的外星敌人。护卫队们使用最先进的战机穿梭于母舰周围,进行巡逻等太空作业。这种战机配备有先进的武器装备,普遍是由一组四个人进行驾驶,其中一名驾驶员,一名导航员,一名机师以及一名武器操纵者,他们被分一组,平时一起训练,以便于执行任务时有足够的契合度来完成危险的星际作业。 
    将军要求的,便是选两组的驾驶员,同样职业的士兵的体重之差尽量大,以满足将军的各种作战需求。 
    现在将军助手调出了所有的驾驶员组的资料,希望你能帮助他完成将军的命令,选出两组驾驶员组,使得同样职业士兵的体重差之和最大。 
    【输入格式】
    输入文件第一行包含一个整数n,表示有n组这样的驾驶员组。(2<=n<=100000) 
    接下来n行,每行四个实数ai,bi,ci,di,分别表示每组驾驶员组的四位士兵的体重。 
    【输出格式】
    要求输出文件中仅包含一个数max,为选出的两组士兵中对应士兵的体重差的和的最大值,保留三位小数。

    input 

    1.0 1.0 2.0 0.5 
    1.0 1.0 0.5 2.0

    output
    3.0000

    数学模型:给定四维空间中N个点的坐标,求两个点,使得他们的曼哈顿距离最大。(难点)
    分析:
    1. 先考虑二维情况
    2. 两个点的曼哈顿距离为|x1-x2|+|y1-y2|
    3. 由于|x1-x2|+|y1-y2|=max{|(x1+y1)-(x2+y2)|,|(x1-x2)-(y1-y2)|}

    (只要|y1-y2|的符号是正还是负,对于|x1-x2|不需要进行考虑。

    因为后面加了绝对值的,|x1-x2|如果为负数的情况会包括进去的)
    4. 所以可以重新定义点的坐标为(A,B)=(x+y,x-y),这样两点的距离便可以表示为dist=max{A1-A2,B1-B2}。相当于把坐标轴旋转了45度(想一想,为什么)
    5. 这样点的原点的距离定义为dist=max{A,B},由于距离相隔最远的两个点也一定距离原点最远,在A方向上求出A坐标的最大值和最小值,设两者差为C,B方向上求出B坐标的最大和最小值,差为D。则答案为max{C,D}
    6. 对于三维情况,分别求出x+y+z,x+y-z,x-y+z,x-y-z的最大最小值差,取最大值作为答案即可。
    7. 四维同样推广

    const
      c:array[1..2] of longint=(-1,1);
    var
      i,j,n,m,k,t,l:longint;
      max,min:array[1..8] of double;
      v,x,y,z,w:double;
    begin
      assign(input,'drivers.in'); reset(input);
      assign(output,'drivers.out'); rewrite(output);
      for j:=1 to 2 do
       for k:=1 to 2 do
        for l:=1 to 2 do
         begin
          inc(t);
          min[t]:=maxlongint;
          max[t]:=-min[t];
         end;
      readln(n);
      for i:=1 to n do
       begin
        readln(x,y,z,w);
        t:=0;
        for j:=1 to 2 do
         for k:=1 to 2 do
          for l:=1 to 2 do
           begin
            inc(t);
            v:=x+y*c[j]+z*c[k]+w*c[l];
            if v>max[t] then max[t]:=v;
            if v<min[t] then min[t]:=v;
           end;
       end;
      x:=0;
      for i:=1 to t do
       begin
        v:=max[i]-min[i];
        if v>x then x:=v;
       end;
      writeln(x:0:3);
      close(input); close(output);
    end.
    

      

  • 相关阅读:
    Java技术学习笔记:C/S 与B/S 区别
    Java开发面试题总结(八)
    Java技术笔记:数据库的性能优化
    零基础学习Python可以学会吗?你有哪些方法?
    java培训学习路线图之SpringBoot多模块开发学习
    计算机专业选Java和Python哪个前景好点?
    bzoj2152 聪聪可可
    bzoj1468 Tree
    bzoj2879 [Noi2012]美食节
    bzoj2208 [Jsoi2010]连通数
  • 原文地址:https://www.cnblogs.com/cutemush/p/14111091.html
Copyright © 2020-2023  润新知