zoukankan      html  css  js  c++  java
  • [BZOJ1857][Scoi2010]传送带

    1857: [Scoi2010]传送带

    Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 1786  Solved: 981 [Submit][Status][Discuss]

    Description

    在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间

    Input

    输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R

    Output

    输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位

    Sample Input

    0 0 0 100
    100 0 100 100
    2 2 1


    Sample Output

    136.60

    HINT

    对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000                  1<=P,Q,R<=10

    路径显然是先在第一条线段上走一段,然后在平面上走一段,再到第二条线段上走一段

    根据生活经验

    如果把点的位置看作自变量,距离看作函数值,那么肯定有一点最优然后两边单调地变劣

    所以可以在第一根线段上三分,然后求最短距离则需要在第二根线段上三分

    #include <cmath>
    #include <cstdio>
    #include <iostream>
    using namespace std;
    double xl1, yl1, xr1, yr1, xl2, yl2, xr2, yr2, len1, len2, xx, yy, p, q, r;
    inline double sqr(const double &x){
        return x * x;
    }
    inline double dis(const double &x1, const double &y1, const double &x2, const double &y2){
        return sqr(x1 - x2) + sqr(y1 - y2);
    }
    inline double calc2(const double &lam){
        double xt = xl2 + lam * (xr2 - xl2), yt = yl2 + lam * (yr2 - yl2);
        return sqrt(dis(xx, yy, xt, yt)) / r + len2 * (1 - lam) / q;
    }
    inline double calc(const double &lam){
        xx = xl1 + lam * (xr1 - xl1), yy = yl1 + lam * (yr1 - yl1);
        double l = 0, r = 1, m1, m2, t1, t2;
        while(r - l > 0.00001){
            m1 = (r + 2 * l) / 3;
            m2 = (2 * r + l) / 3;
            t1 = calc2(m1);
            t2 = calc2(m2);
            if(t1 > t2) l = m1;
            else r = m2;
        }
        return len1 * lam / p + min(t1, t2);
    }
    int main(){
        cin >> xl1 >> yl1 >> xr1 >> yr1 >> xl2 >> yl2 >> xr2 >> yr2 >> p >> q >> r;
        len1 = sqrt(dis(xl1, yl1, xr1, yr1));
        len2 = sqrt(dis(xl2, yl2, xr2, yr2));
        double l = 0, r = 1, m1, m2, t1, t2;
        while(r - l > 0.00001){
            m1 = (r + 2 * l) / 3;
            m2 = (2 * r + l) / 3;
            t1 = calc(m1);
            t2 = calc(m2);
            if(t1 > t2) l = m1;
            else r = m2;
        }
        printf("%.2lf", min(t1, t2));
        return 0;
    }
  • 相关阅读:
    协变与逆变
    反射
    TreeCombo
    使用TreeCombo示例
    Calling R from java using JRI
    [转]相似度计算常用方法综述
    [转]聚类算法KMeans, KMedoids, GMM, Spectral clustering,Ncut
    Learning D3.js with App iLearning D3.js
    [repost ]经典的机器学习方面源代码库
    [转]数据挖掘中所需的概率论与数理统计知识、上
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7768677.html
Copyright © 2011-2022 走看看