P2571 [SCOI2010]传送带

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)); 
}
posted @ 2020-09-16 20:48  Gensokyo_Alice  阅读(100)  评论(0编辑  收藏  举报