题解 | #[SCOI2010]传送带#

[SCOI2010]传送带

https://ac.nowcoder.com/acm/problem/20276

对CD来说进早了可能因为路远,时间增大,进晚了因为没有省力所以时间增大,故区间是一个凹状的,可以使用三分去解决。对于何时进入CD也是一样的。故嵌套三分的做法。
但因为本题针对实数的运算,所以要求精度。至于为什么要在计算距离时加上精度,我想是因为在求距离过程中小数位会有所丢失的原因吧。所以需要加上(当然这只是我的想法)。
按雨巨的另一种做法,直接固定循环次数也可以。
#include <bits/stdc++.h>

using namespace std;

struct Node{
    double x;
    double y;
} a,b,c,d, ab, cd;
double P,Q,R;

const double eqs = 1e-8;
double dist(Node a, Node b) {
    return sqrt(1e-11+pow(a.x-b.x, 2)+pow(a.y-b.y, 2));
}

double calc2(double m) {
    cd.x = c.x+(m/dist(c, d)*(d.x-c.x));
    cd.y = c.y+(m/dist(c, d)*(d.y-c.y));
    double time1 = dist(ab, cd)/R;
    double time2 = dist(cd, d)/Q;
    return time1+time2;
}

double calc(double m) 
{
    ab.x = a.x+(m/dist(a,b)*(b.x-a.x));
    ab.y = a.y+(m/dist(a,b)*(b.y-a.y));
    double time1 = m/P;
    double l = 0, r = dist(c, d);
    double ans = 10000;
    while (r-l>eqs) {
        double m1 = l+(r-l)/3;
        double m2 = r-(r-l)/3;
        if (calc2(m2)-calc2(m1)>eqs) {
            ans = calc2(m1);
            r = m2;
        } else {
            ans = calc2(m2);
            l = m1;
        }
    }
    return ans+time1;
}

int main() {
    cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y;
    cin>>P>>Q>>R;
    double ans = 1000;
    double l=0, r = dist(a, b);
    while (r-l>eqs) {
        double m1 = l+(r-l)/3;
        double m2 = r-(r-l)/3;
        if (calc(m2)-calc(m1)>eqs) {
            ans = calc(m1);
            r = m2;
        } else {
            ans = calc(m2);
            l = m1;
        }
    }
    printf("%.2lf", ans);
    return 0;
}


全部评论

相关推荐

07-17 11:56
门头沟学院 Java
感谢东子的收留
熬夜脱发码农:无敌了,这是我看到第二个京东的提前批大佬了我还在畏畏缩缩准备八股算法
点赞 评论 收藏
分享
醉蟀:你不干有的是人干
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务