2019 Multi-University Training Contest 1

http://acm.hdu.edu.cn/showproblem.php?pid=6581

一开始想了好几个假算法。但是启发了一下潘哥,假如时间知道的话就可以从头开始确定各个车的位置。那么直接 (O(log_2frac{10^9}{10^{-6}})) 二分时间 (t) ,然后 (O(n)) 验证。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000;
const double eps = 1e-9;
int l[maxn + 5], s[maxn + 5], v[maxn + 5], n;
double pos[maxn];

inline bool check(double t) {
    pos[n - 1] = t * v[n - 1] + s[n - 1] - l[n - 1];
    for(int i = n - 2; i >= 0; --i) {
        if(t * v[i] + s[i] >= pos[i + 1])
            pos[i] = pos[i + 1] - l[i];
        else
            pos[i] = t * v[i] + s[i] - l[i];
    }
    return pos[0] + l[0] >= -eps;
}

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    while(~scanf("%d", &n)) {
        ++n;
        for(int i = 0; i < n; ++i)
            scanf("%d", l + i);
        for(int i = 0; i < n; ++i)
            scanf("%d", s + i), s[i] = -s[i];
        for(int i = 0; i < n; ++i)
            scanf("%d", v + i);
        double l = 0.0, r = 1e9;
        while(r - l >= eps) {
            double mid = (l + r) / 2.0;
            if(check(mid))
                r = mid;
            else
                l = mid;
        }
        printf("%.8f
", l);
    }
    return 0;
}

其实最后一辆车一定会和前面的某个连续区间内的车组成“动车组”,然后以“车头”的速度持续开到终点。枚举这个时间的最大值就知道最终谁是“动车组”的“车头”。

原文地址:https://www.cnblogs.com/Yinku/p/11227690.html