• P2571 [SCOI2010]传送带


    链接:https://www.luogu.org/problemnew/show/P2571

    题目描述

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

    输入输出格式

    输入格式:

    输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By

    第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy

    第三行是3个整数,分别是P,Q,R

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    0 0 0 100
    100 0 100 100
    2 2 1
    
    输出样例#1: 复制
    136.60

    说明

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

                 1<=P,Q,R<=10
    题解:

    三分套。
    • 首先如果确定了 AB 上从哪个点离开,那么 上从哪个点离开,那么 上从哪个点离开,那么 CD 上点的 上点的 距离函数一定是个单谷,可以三分来求。 
    • 如何求解 AB 上的点呢?
    • 他也满足单谷的性质,可以三分来求。用CD上的点来更新AB上的点

    #include<bits/stdc++.h>
    using namespace std;
    
    const double eps = 1e-6;
    double Ax, Ay, Bx, By, Cx, Cy, Dx, Dy, p, q, r;
    double dis(double x1, double y1, double x2, double y2){
        return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    }
    double work(double nx, double ny){
        double lf = Cx, rg = Dx, hlf = Cy, hrg = Dy, ans = 1000000008;
        while(1){
            double midx = (lf + rg) / 2, midy = (hlf + hrg) / 2;
            double midxm = (midx + rg) / 2, midym = (midy + hrg) / 2;    
            double tmp1 = dis(nx, ny, midx, midy)/r + dis(Ax, Ay, nx, ny)/ p + dis(midx, midy, Dx, Dy)/q;
            double tmp2 = dis(nx, ny, midxm, midym)/r + dis(Ax, Ay, nx, ny)/ p + dis(midxm, midym, Dx, Dy)/q;
            if(tmp1 < tmp2) rg = midxm, hrg = midym;
            else lf = midx, hlf = midy;
            ans = min(ans, min(tmp1, tmp2));
        //    printf("%lf %lf
    ", tmp1, tmp2);
            if(fabs(midx-midxm) < eps && fabs(midy-midym) < eps)break;
        }
        return ans;
        
    }
    
    int main(){
        double ans = 100000000008;
        
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", &Ax, &Ay, &Bx, &By, &Cx, &Cy, &Dx, &Dy, &p, &q, &r);
        double lf = Ax, rg = Bx, hlf = Ay, hrg = By;
        while(1){
            double midx = (lf + rg) / 2, midy = (hlf + hrg) / 2;
            double midxm = (midx + rg) / 2, midym = (midy + hrg) / 2;
            double ans1 = work(midx, midy), ans2 = work(midxm, midym);
            if(ans1 < ans2) rg = midxm, hrg = midym;
            else lf = midx, hlf = midy;
            ans = min(ans, min(ans1, ans2));
            if(fabs(midx-midxm) < eps && fabs(midy-midym) < eps)break;
        } 
        printf("%.2lf
    ", ans);
    }
    View Code
  • 相关阅读:
    Android平台Qt开发入门教程 狼人:
    PySide教程:第一个PySide应用 狼人:
    MeeGo系统1.2版本新组件 狼人:
    讨论:.NET 4各项技术的应用前景,徐汇区网站设计 狼人:
    为 NokiaQt SDK增加新的Symbian SDK开发平台 狼人:
    Skia引擎API整理介绍(skia in Android 2.3 trunk) 狼人:
    Windows Phone 7 开发之:工具栏 狼人:
    Google Adsense(Google网站联盟)广告申请指南 狼人:
    PySide教程:一个简单的点击按钮示例 狼人:
    内部类类4线程两加两减
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9277885.html
Copyright © 2020-2023  润新知