P2571 [SCOI2010]传送带
三分套三分,在 \(AB\),\(CD\) 上任意选两个点,对于其中一个点固定的情况,其决策一定是一个凸函数。自己画一下模拟一下就知道了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
typedef double dd;
const ll MAXN = 1e6+10;
const dd ep = 1e-6;
struct point {
dd x, y;
} A, B, C, D;
dd P, Q, R;
dd div1();
dd div2(point);
dd dis(point, point);
int main() {
scanf("%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y);
scanf("%lf%lf%lf%lf", &C.x, &C.y, &D.x, &D.y);
scanf("%lf%lf%lf", &P, &Q, &R);
printf("%.2f", div1());
return 0;
}
dd div1() {
point a = A, b = B;
while (dis(a, b) >= ep) {
dd tmpx = (b.x - a.x) / 3.0, tmpy = (b.y - a.y) / 3.0;
point l, r;
l.x = a.x + tmpx, l.y = a.y + tmpy;
r.x = b.x - tmpx, r.y = b.y - tmpy;
dd lans = div2(l) + dis(A, l) / P;
dd rans = div2(r) + dis(A, r) / P;
if (rans - lans > ep) b = r;
else a = l;
}
return dis(A, a) / P + div2(a);
}
dd div2(point tem) {
point c = C, d = D;
while (dis(c, d) >= ep) {
dd tmpx = (d.x - c.x) / 3.0, tmpy = (d.y - c.y) / 3.0;
point l, r;
l.x = c.x + tmpx, l.y = c.y + tmpy;
r.x = d.x - tmpx, r.y = d.y - tmpy;
dd lans = dis(tem, l) / R + dis(l, D) / Q;
dd rans = dis(tem, r) / R + dis(r, D) / Q;
if (rans - lans >= ep) d = r;
else c = l;
}
return dis(tem, c) / R + dis(c, D) / Q;
}
dd dis(point a, point b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
希望我们都有一个光明的未来