[ICPC2020上海D] Walker - 貪心
阿新 • • 發佈:2020-12-17
[ICPC2020上海D] Walker - 貪心
Description
給定一個長度為 \(n\) 的數軸,有兩個人分別位於 \(p_1,p_2\),走路速度為 \(v_1,v_2\),求覆蓋完整個數軸的最短時間。
Solution
考慮二分時間 \(t\),顯然兩個人走路過程不對穿一定不會更劣,換言之我們可以把數軸劃分為兩部分分別分給兩個人。
於是在判定時,我們要做的,是計算 \(f(p_1,v_1,t) + f(n-p_2,v_2,t) \ge n\) 是否成立。
現在考慮 \(f(p,v,t)\) 的計算過程,其中 \(p\) 代表的是到端點的距離。
顯然有兩種方案,一種是走到中間點再回來,一種是走到端點再回來,如果能滿足 \(p \ge vt\)
#include <bits/stdc++.h> using namespace std; #define int long long double f(double p, double v, double t) { if (v * t < p) return 0; return max(p, max(v * t - p, p + (v * t - p) / 2)); } bool check(double p1, double v1, double p2, double v2, double t, double n) { return f(p1, v1, t) + f(n - p2, v2, t) > n || f(n - p1, v1, t) + f(p2, v2, t) > n; } signed main() { ios::sync_with_stdio(false); int t; cin >> t; while (t--) { double n, p1, v1, p2, v2; cin >> n >> p1 >> v1 >> p2 >> v2; double l = 0, r = 1e18; for (int _ = 0; _ <= 100; _++) { double mid = (l + r) / 2; if (check(p1, v1, p2, v2, mid, n)) r = mid; else l = mid; } cout << setiosflags(ios::fixed) << setprecision(12) << l << endl; } }