空中飞猴 题解 暴力

来源:互联网 发布:淘宝联盟东西是真的吗 编辑:程序博客网 时间:2024/04/29 19:32

题目描述

马戏团里新来了一只很特别的小猴子,不仅长得漂亮,还很聪明。自从它来到马戏团之后,“空中飞猴”成了马戏团里的保留节目,慕名观看的人络绎不绝。

“空中飞猴”表演开始时,空中架着两根长长的钢丝。峰峰在其中一根上,它的目标是到达另一个根钢丝上,必须在爬行一定距离后纵身一跃,直接跳到另一根钢丝的某个位置。由于它的速度非常快,它的运动轨迹可以近似的看成一条直线段。为了不让自己太危险,希望自己的跳跃距离尽量短,而为了不让观众等得太不耐烦,它在钢丝上的爬行距离不能超过d。

请你求出在爬行距离不超过d的情况下,峰峰的跳跃距离最短是多少?

....据说三分可做?并没有得到证明= =...

....据说计算几何?然而蒟蒻并不会= =...

虽然暴力的时间复杂度很迷,正确性很迷,和乱搞是没有什么区别的,但是居然就这么过了....= =

果然暴力出奇迹不是骗人的。

最短的跳跃距离,就是从小猴所在钢丝l1上,找到一点,然后再从另一根钢丝l2上,找到该点最短的落点,然后求个dis就行...

因为它都是实数,蒟蒻并不知道怎么枚举...

看了一下标程,设了一个delta[i]数组,delta[i]=(1/4)^(-i),1<=i<=14

然后以delta[i]为枚举步长乱搞...并不知道为什么

对于在l1上的起点now的要求:

(1)dis(小猴起点,now)<=d

(2)now在线段l1上,即到两端点的距离都小于等于长度

对于l2上落点arrive的要求:

(1)min(dis(now,arrive))

(2)arrive在线段l2上,即到两端点距离小于等于长度

type        rec=record            x,y,z:real;end;var        p1,p2,p3,p4,p5   :rec;        ans,len1,len2,d  :real;        now,mid          :rec;        change_foot      :rec;        v1,v2            :rec;        t                :rec;        cas              :longint;        i                :longint;        delta            :array[0..14] of real;function plus(a,b:rec):rec;var        c:rec;begin   c.x:=a.x+b.x;   c.y:=a.y+b.y;   c.z:=a.z+b.z;   exit(c);end;function mul(a:rec;b:real):rec;var        c:rec;begin   c.x:=a.x*b;   c.y:=a.y*b;   c.z:=a.z*b;   exit(c);end;function sub(a,b:rec):rec;var        c:rec;begin   c.x:=a.x-b.x;   c.y:=a.y-b.y;   c.z:=a.z-b.z;   exit(c);end;function dis(a,b:rec):real;begin   exit( sqrt( sqr(a.x-b.x) + sqr(a.y-b.y) + sqr(a.z-b.z) ) );end;function work(pos:rec):real;var        arrive,tt:rec;        ans:real;        i:longint;begin   arrive:=mid;   ans:=dis(arrive,pos);   for i:=1 to 14 do   begin      tt:=mul(v2,delta[i]);      while (dis(plus(arrive,tt),pos)<ans) and (dis(plus(arrive,tt),mid)<=len2/2)  do      begin         arrive:=plus(arrive,tt);         ans:=dis(pos,arrive);      end;      while (dis(pos,sub(arrive,tt))<ans) and (dis(sub(arrive,tt),mid)<=len2/2)  do      begin         arrive:=sub(arrive,tt);         ans:=dis(pos,arrive);      end;   end;   exit(ans);end;procedure check(delta:rec);var        tt:rec;        tans:double;begin   while true do   begin      tt:=plus(delta,now);      if (dis(tt,p5)>d) then break;      if (dis(tt,p1)>len1) then break;      if (dis(tt,p2)>len1) then break;      tans:=work(tt);      if tans<ans then      begin         ans:=tans;         now:=tt;      end else break;   end;end;begin   //assign(input,'mky.in');reset(input);   //assign(output,'mky.out');rewrite(output);   delta[0]:=1;   for i:=1 to 14 do delta[i]:=1/4*delta[i-1];   read(cas);   while (cas>0) do   begin      dec(cas);      read(p1.x,p1.y,p1.z,p2.x,p2.y,p2.z,p3.x,p3.y,p3.z,p4.x,p4.y,p4.z,p5.x,p5.y,p5.z,d);      len1:=dis(p1,p2);      len2:=dis(p3,p4);      v1:=sub(p2,p1);      v2:=sub(p4,p3);      mid:=mul(plus(p3,p4),0.5);      ans:=work(p5);      now:=p5;      //      for i:=1 to 14 do      begin         change_foot:=mul(v1,delta[i]);         check(change_foot);         change_foot:=mul(v1,-delta[i]);         check(change_foot);      end;      writeln(ans:0:3);      readln;   end;   //close(input);close(output);end.
——by Eirlys



0 0
原创粉丝点击