分析
我们可以发现总共可以分一下情况:
- 一个人走完全程
- 两个人交叉走(不回头)
- 一个人走一部分,路径不交叉
前两种情况我们可以直接算出来,后面的一种我们要将路程分为两段,一段 p1 跑,一段 p2 跑,两个人跑完的时间越接近,情况越优。所以我们可以二分分割点(肯定在 p1 和 p2 之间)。
代码
#include<bits/stdc++.h>
using namespace std;double n,p1,v1,p2,v2;
double eps = 1e-8;void solve()
{
cin>>n>>p1>>v1>>p2>>v2;if(p1 > p2) swap(p1, p2), swap(v1, v2);double ans = (p1 + n) / v1;//单人走完全程 ans = min(ans, (2.0 * n - p1) / v1);ans = min(ans, (p2 + n) / v2);ans = min(ans, (2.0 * n - p2) / v2);ans = min(ans, max(p2 / v2, (n - p1) / v1));//两人交叉走 double l = p1, r = p2;while(r - l > eps){
double mid = (l + r) / 2.0;double t1 = min(2.0 * mid - p1, p1 + mid) / v1;double t2 = min(n - mid + p2 - mid, n - mid + n - p2) / v2;ans = min(ans, max(t1, t2));if(t1 > t2) r = mid;else l = mid;}printf("%.10lf\n",ans);
}int main()
{
int T;cin>>T;while(T--){
solve();}return 0;
}