「題解」洛谷 P2571 [SCOI2010]傳送帶
阿新 • • 發佈:2020-08-25
題目
思路
三分套三分。
直接給結論,不會證明,感性理解一下。
設 \(E\) 是線段 \(AB\) 上的一點,\(F\) 是 \(CD\) 上的一點,所走的一定是 \(A \rightarrow E \rightarrow \rightarrow F \rightarrow D\)。
結論:三分 \(E\) 所在的點,三分 \(F\) 所在的點,也就是說 計算\(E\) 到 \(F\) 加上 \(F\) 到 \(D\) 的時間是個單峰函式, 然後計算總的時間也是個單峰函式。
Code
#include <cmath> #include <cstdio> #include <cstring> #include <string> #include <iostream> #include <algorithm> #define eps 1e-8 double ax, ay, bx, by, cx, cy, dx, dy, p, q, r; double getd(double x1, double y1, double x2, double y2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } double f(double x1, double y1, double x2, double y2) { double t2 = getd(x1, y1, x2, y2) / r; double t3 =getd(x2, y2, dx, dy) / q; return t2 + t3; } double work(double x, double y) { double t1 = getd(ax, ay, x, y) / p; double lx = cx, ly = cy, rx = dx, ry = dy; while (getd(lx, ly, rx, ry) > eps) { double lmidx = lx + (rx - lx) / 3.0, lmidy = ly + (ry - ly) / 3.0; double rmidx = rx - (rx - lx) / 3.0, rmidy = ry - (ry - ly) / 3.0; double ans1 = f(x, y, lmidx, lmidy), ans2 = f(x, y, rmidx, rmidy); if (ans2 - ans1 > eps) rx = rmidx, ry = rmidy; else lx = lmidx, ly = lmidy; } return t1 + f(x, y, lx, ly); } int main() { scanf("%lf %lf %lf %lf", &ax, &ay, &bx, &by); scanf("%lf %lf %lf %lf", &cx, &cy, &dx, &dy); scanf("%lf %lf %lf", &p, &q, &r); double lx = ax, ly = ay, rx = bx, ry = by; while (getd(lx, ly, rx, ry) > eps) { double lmidx = lx + (rx - lx) / 3.0, lmidy = ly + (ry - ly) / 3.0; double rmidx = rx - (rx - lx) / 3.0, rmidy = ry - (ry - ly) / 3.0; //std::cout << lmidx << " " << lmidy << '\n'; //std::cout << rmidx << " " << rmidy << '\n'; double ans1 = work(lmidx, lmidy), ans2 = work(rmidx, rmidy); //std::cout << ans1 << " " << ans2 << '\n'; if (ans2 - ans1 > eps) rx = rmidx, ry = rmidy; else lx = lmidx, ly = lmidy; } printf("%.2lf", work(lx, ly)); return 0; }