思路
- 将所有点按照
y
升序排序,y
相同按照x
升序排序 - 首先check一下可不可以直接通过,可以就直接输出
- 枚举每个
y
- 计算奶牛到这儿需要的时间
- 查看车能不能撞到奶牛
车在往左走,等价于奶牛右走,所以比较
v * t > p[i].x
即可
- 枚举每个
- 如果不行
- 还是等价于奶牛右走
- 枚举每个
y
- 如果奶牛当前的
x
在车的右边,跳过 - 如果奶牛当前的
x
在车的左边- 计算到
y
所需要的时间dt
- 如果全速行走导致奶牛会凭空穿过车(
u * dt + py > p[i].y
), 则奶牛走到y
(py = p[i].y
) - 否则全速走
- 然后更新时间和
x
即可
- 计算到
- 最后如果没走到马路对面,全速走即可
注意:cout
需要指定小数位数( cout << fixed << setprecision(6)
),否则部分点WA
时间复杂度
排序的$O(n \log n)$ 吧
这里为了方便排序,把y总的板子
#define x first
#define y second
改为
#define y first
#define x second
C++ 代码
#include <bits/stdc++.h>
#define endl '\n'
#define y first
#define x second
using namespace std;
using PII = pair<int, int>;
const int N = 1e4 + 5, eps = 1e-10;
int n;
double w, v, u;
PII p[N];
inline bool check()
{
double t = 0, px = 0, py = 0;
for (int i = 0; i < n; ++ i)
{
t = p[i].y / u;
if (v * t > p[i].x) return false;
}
return true;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> w >> v >> u;
for (int i = 0; i < n; ++ i) cin >> p[i].x >> p[i].y;
sort(p, p + n);
if (check())
{
printf("%.10f\n", w / u);
return 0;
}
double t = 0, px = 0, py = 0;
for (int i = 0; i < n; ++ i)
{
while (i < n && px > p[i].x) ++ i;
if (i == n) break;
double dt = (p[i].x - px) / v;
if (u * dt + py >= p[i].y) py = p[i].y;
else py += u * dt;
t += dt, px = p[i].x;
}
if (w - py > eps) t += (w - py) / u;
printf("%.10f\n", t);
return 0;
}