题目
你从(0,0)出发到(0,w)
有一辆由n个点组成的多边形车
第i个点是(xi,yi),0<=yi<=w
行人速度v,车速度u向左行驶
问不被撞到的情况下,到达w的最短时间
思路来源
https://blog.youkuaiyun.com/aozil_yang/article/details/52132400
题解
这思维题绝了 我自己做真想不出来
考虑有一个点(xi,yi)人走到(0,yi)的时候,这个点走到了哪里
如果这个点在y轴右侧,说明还没到y轴,还没有撞上行人
而这个点在y轴左侧,说明这个点已经过y轴了
考虑若干个点的情形,
如果所有点都在y轴左侧了,说明这辆车过去了,根本不会撞到
同理,如果所有点都在y轴右侧,说明人走到对应点的时候,车还没到,也不会被撞
考虑有的点在y轴左侧,有的在y轴右侧
比如(xi,yi)在人到的时候在左侧,(xj,yj)在人到的时候在右侧
那么根据零点定理,这两点确定的直线与y轴必有交点,
那么人走的轨迹(0,yi)、(0,yj)确定的直线,
势必会与这条直线有交点,表示人被扫中,
由于这条直线是车内部的直线(至少是边缘线),
交点说明在那一刻人这个点在车里面,
那不就GG了么……
撞了的话会被连撞多久呢,
等那个对应时刻下最右边的点过了y轴就不会被撞了
那我们晚出发这么多时间,就彻底不会被撞了
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-7;
int n;
double w,v,u,mx,mn;
//0<=yi<=w很重要,不然就不好做了QAQ
int main()
{
while(~scanf("%d%lf%lf%lf",&n,&w,&v,&u))
{
for(int i=0;i<n;++i)
{
double x,y;
scanf("%lf%lf",&x,&y);
if(!i)mx=mn=x-y/u*v;//(0,0)->(0,y)的时间y/u下(x,y)以v速度到哪里了
else mx=max(mx,x-y/u*v),mn=min(mn,x-y/u*v);
}
if(mx<eps||mn>-eps)printf("%.7lf\n",w/u);//直接走过 不会撞到
else printf("%.7lf\n",w/u+mx/v);//等mx/v秒车过去了就不会被撞
}
return 0;
}