1. 程式人生 > 實用技巧 >ICPC D.Walker

ICPC D.Walker

題目連結
思路
一共分三種情況
1.一個人走完所有的路
2.兩個人交叉走完所有的路
3. 兩個人各負責自己的一邊,然後在中間相遇,那麼對於每個人,有兩種選擇,一種是先往端點走,一種是先往中間走,那麼我們可以二分走到中間點的位置,就能夠算出每個人往中間最多能走多少時間,判斷一下左右所用時間大小就餓可以了
程式碼

#include <bits/stdc++.h>

//#define min(a,b,c) min(a,min(b,c))

using namespace std;

const double eps = 1e-8;

int main()
{
    int _; cin >> _;
    while(_ --){
        double n,p1,v1,p2,v2;
        cin >> n >> p1 >> v1 >> p2 >> v2;
        
        if(p1 > p2){
            swap(p1,p2);
            swap(v1,v2);
        }
        
        double ans =  1e20;
        
        // 一個人走完所有路程
        ans = min(ans, min(p1 + n, n + n - p1) / v1);
        ans = min(ans, min(n - p2 + n ,  p2 + n) / v2);
        
        // 兩個人交叉走完對方的路程
        ans = min(ans, max((n - p1) / v1, p2 / v2));
        
        // 兩個人各走各的
        double l = p1, r = p2;
        while(r - l > eps){
            double mid = (l + r) / 2;
            
            double lt = min(mid + p1 , mid + mid - p1) / v1;
            double rt = min(n - mid + n - p2, p2 - mid + n - mid) / v2;
            ans = min(ans,max(lt,rt));
            
            if(lt <= rt) l = mid; // 如果左邊用的時間少於右邊用的那就說明二分的點靠左了
            else r = mid;
        }
        printf("%.8f\n",ans);
    }
}