B. Meeting on the Line

https://codeforces.com/problemset/problem/1730/B

题意:给定长度为n的数组x和t,x代表所在的位置,位置可以移动,t代表移动前需要准备的时间。找一个point,使得x中的所有数字可以在最短的时间内全部到达。

思路:在时间域上二分,因为坐标可能是0.5的小数,所以将所有原始数据扩大一倍。随后,在二分时判断对于当前的时间节点T,如果T<t[i],则说明无解,因为还没有准备完,就没时间了。否则,求出当前x可以在T内到达的区间[x[i] -(T - t[i]), x[i] + (T - t[i])],然后对n个x求解区间交集,如果区间有交集,则说明在时间T内,x数组中所有的数字都可以在时间T内到达这个区间内,T是合法的,R左移,否则T不合法L右移。

总结:

inline void solve() {
    int n;
    cin >> n;

    vector<int> x(n);
    vector<int> t(n);
    for (auto& a : x) {
        cin >> a;
        a <<= 1;
    }
    for (auto& v: t) {
        cin >> v;
        v <<= 1;
    }

    int ans;
    auto valid = [&](int time) {
        int l, r;
        for (int i = 0; i < n; ++i) {
            if (time < t[i]) {
                return false;
            }
            int curLeft = x[i] - (time - t[i]);
            int curRight = x[i] + (time - t[i]);
            if (i) {
                if (curRight < l || r < curLeft) {
                    return false;
                }
                l = max(l, curLeft);
                r = min(r, curRight);
            }
            else {
                l = curLeft;
                r = curRight;
            }
        }    
        ans = r;
        return true;    
    };

    int l = 0, r = 4e8 + 10;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (valid(mid)) {
            r = mid;
        }
        else {
            l = mid + 1;
        }
    }

    if (ans & 1) {
        cout << ans / 2 << ".5" << '\n';
    }
    else {
        cout << ans / 2 << '\n';
    }
}
posted @ 2025-10-31 10:43  _Yxc  阅读(1)  评论(0)    收藏  举报