Walker(分类模拟 + 二分)
题目:
给定一个数轴,其上有两个可以自由向左向右前进的人,询问什么时候整个数轴至少有一个人来过。
AC代码
#include <bits/stdc++.h>
using namespace std;
double get_time(double n, double p, double v)
{
return (n + min(p, n - p)) / v;
}
void solve()
{
double n, p1, p2, v1, v2;
cin >> n >> p1 >> v1 >> p2 >> v2;
//规定 p1小于p2
if (p1 > p2)
swap(p1, p2), swap(v1, v2);
//1.速度差距过大 覆盖时间取决于单个
double ans = get_time(n, p1, v1);
ans = min(ans, get_time(n, p2, v2));
//2. 二者碰面后不回头
ans = min(ans, max((n - p1) / v1, p2 / v2));
//3. 二者在某中间点碰面后回头 二分中点逼近时间
double l = p1, r = p2;
for (int i = 1; i <= 100; i++)
{
double mid = (l + r) / 2;
double t1 = get_time(mid, p1, v1);
double t2 = get_time(n - mid, p2 - mid, v2);//细节更新总长时 p2坐标也要偏移
ans = min(ans, max(t1, t2));
if (t1 < t2)//如果 让快的跑更多的路 慢的少跑路
l = mid;
else
r = mid;
}
printf("%.10f\n", ans);
}
int main()
{
int T;
cin >> T;
while (T--)
solve();
return 0;
}
while (T--)
solve();
return 0;
}