题意
行人要在不被撞的前提下经过马路(被撞定义为坐标在车内,边界不算),行人速度可变( 0≤v≤u )汽车速度恒定。汽车为凸多边形,给定 n,w,v,u ,分别表示汽车的角点数,路宽,车速,行人速度,车速为 −x 方向,行人速度为 +y 方向,要求行人过马路的最少时间。
思路
情况一共有两种
1. 整个行走过程中车都在行人右侧
2. 车已经在y轴左侧或行人走一段停下等车过去一部分后贴着车的右侧边缘前进
我们定义
t1=xv
,
t2=yu
,分别表示汽车的某个角点到达y轴与行人到达对应点所需的时间。
- 当且仅当所有的角点都满足
p[i].xv≥p[i].yu
,情况1满足
- 对于情况2当且仅当所有的角点都满足
p[i].xv≤p[i].yu+waitTime
,即行人等待一段时间并到达终点的总时间要小于等于车到y轴的时间(车已经过去了)。
-对于情况1,答案为
w/u
-对于情况2,有两种方法求出答案:
2.1
w−p[i].yu+p[i].xv
中的最大值,表示时间为汽车通过和行人走过剩下路程的时间和
2.2 二分等待时间,要求等待时间满足上述条件
代码
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<b;i++)
#define debug(a) printf("a =: %d\n",a);
const int INF=0x3f3f3f3f;
const int maxn=1e4+50;
const int Mod=1000000007;
const double eps=1e-12;
const double PI=acos(-1);
typedef long long ll;
using namespace std;
struct Point{
int x,y;
};
Point p[maxn];
int n;
double w,u,v;
bool check(){
for(int i=0;i<n;i++){
if (p[i].x/v<p[i].y/u) return false;
}
return true;
}
bool check2(double waitTime){
for(int i=0;i<n;i++){
if (p[i].x/v>p[i].y/u+waitTime) return false;
}
return true;
}
double solve(){
double ret=w/u;
if (check()) ret=w/u;
else{
for(int i=0;i<n;i++){
ret=max(ret,(w-p[i].y)/u+p[i].x/v);
}
/*
double l=0,r=0;
for(int i=0;i<n;i++) r=max(r,p[i].x/v);
while(r-l>eps){
double mid=(l+r)/2;
if (check2(mid)) r=mid;
else l=mid;
}
ret=l+w/u;
*/
}
return ret;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int ww,vv,uu;
while(scanf("%d %d %d %d",&n,&ww,&vv,&uu)!=EOF){
w=ww; v=vv; u=uu;
for(int i=0;i<n;i++) scanf("%d %d",&p[i].x,&p[i].y);
printf("%.9lf\n",solve());
}
return 0;
}