1 条题解

  • 0
    @ 2026-10-27 13:20:34

    思路与算法

    用参数t,u∈[0,1]表示X=A+t(B−A)、Y=C+u(D−C)。时间为|AX|/P+|XY|/R+|YD|/Q。固定t,对u三分求最优;把这个最优值视为t的函数,再外层三分,输出所得时间。零长度线段无需除线段长度,参数表示仍有效。

    正确性说明

    前后两项是参数的线性函数,中间项是仿射向量的欧氏范数,因此联合目标是凸函数。固定t后的u截面凸,三分保留最小点;在凸集合[0,1]上对u取下确界后,关于t仍凸,外层三分也有效。连续性与紧致区间保证最优值存在,端点最优可由收缩区间逼近。100轮三分后参数区间乘(2/3)^100,路径长度的Lipschitz界由线段长度和最小速度给出,远小于公开误差。

    复杂度

    初始化O(1),内外各100轮、每次常数次距离,总约O(100²)时间、O(1)空间;若精度参数δ显式计,O(log²(1/δ))。

    易错点

    三段速度按P、R、Q对应,CD只走Y到D。端点、重合点、零长度线段均合法,不能对线段长度作不安全除法。按题面公开数值误差判定,不把金答案高精度字符串逐字比较。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    using D = long double;
    struct P {
        D x, y;
    };
    D dist(P a, P b) {
        return hypotl(a.x - b.x, a.y - b.y);
    }
    P mix(P a, P b, D t) {
        return {a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t};
    }
    int main() {
        P A, B, C, Dd;
        D p, q, r;
        cin >> A.x >> A.y >> B.x >> B.y >> C.x >> C.y >> Dd.x >> Dd.y >> p >> q >> r;
        auto inner = [&](D t) {
            P x = mix(A, B, t);
            auto f = [&](D v) {
                P y = mix(C, Dd, v);
                return dist(A, x) / p + dist(x, y) / r + dist(y, Dd) / q;
            };
            D l = 0, h = 1;
            for (int i = 0; i < 100; i++) {
                D a = (2 * l + h) / 3, b = (l + 2 * h) / 3;
                if (f(a) < f(b))
                    h = b;
                else
                    l = a;
            }
            return f((l + h) / 2);
        };
        D l = 0, h = 1;
        for (int i = 0; i < 100; i++) {
            D a = (2 * l + h) / 3, b = (l + 2 * h) / 3;
            if (inner(a) < inner(b))
                h = b;
            else
                l = a;
        }
        cout << fixed << setprecision(2) << inner((l + h) / 2) << '\n';
    }
    
    • 1

    信息

    ID
    2098
    时间
    2000ms
    内存
    64MiB
    难度
    普及+
    标签
    递交数
    0
    已通过
    0
    上传者