zoukankan      html  css  js  c++  java
  • P2571 [SCOI2010]传送带

    P2571 [SCOI2010]传送带

    三分套三分。

    前提条件:P3382 【模板】三分法

    三分,求区间内单峰函数的最大/最小值。

    我们把两条线段都跑三分,先ab后cd,求出最小值。

    可以直接将二维坐标进行三分,为了方便编写,不一定非要取三等分点。代码中取的是中点和一个四等分点。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef double db;
    inline db _min(const db &a,const db &b) {return a<b ?a:b;}
    const db eps=1e-7;
    struct node{db x,y;}a,b,c,d; //存坐标
    db p,q,r;
    inline db dist(node &A,node &B) {return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));}
    inline db F(node &n,node &m) {return dist(a,n)/p+dist(n,m)/r+dist(m,d)/q;} //总距离计算
    inline db sec(node &A){
        node l1=c,r1=d,l2,r2; db ans=1e9;
        do{
            l2.x=(l1.x+r1.x)/2.0,l2.y=(l1.y+r1.y)/2.0;
            r2.x=(l2.x+r1.x)/2.0,r2.y=(l2.y+r1.y)/2.0;
            db q1=F(A,l2),q2=F(A,r2);
            if(q1>q2) l1=l2;
            else r1=r2;
            ans=_min(ans,_min(q1,q2));
        }while(fabs(r1.x-l1.x)>=eps||fabs(r1.y-l1.y)>=eps);
        return ans;
    }
    int main(){
        scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
        scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
        scanf("%lf%lf%lf",&p,&q,&r);
        node l1=a,r1=b,l2,r2; db ans=1e9;
        do{
            l2.x=(l1.x+r1.x)/2.0,l2.y=(l1.y+r1.y)/2.0; //取中点
            r2.x=(l2.x+r1.x)/2.0,r2.y=(l2.y+r1.y)/2.0; //取四等分点
            db q1=sec(l2),q2=sec(r2); //在cd上三分
            if(q1>q2) l1=l2;
            else r1=r2;
            ans=_min(ans,_min(q1,q2));
        }while(fabs(r1.x-l1.x)>=eps||fabs(r1.y-l1.y)>=eps); //使用do-while循环是防止线段退化成一个点的情况时直接跳出(如a,b重合)
        printf("%.2lf",ans);
        return 0;
    }
  • 相关阅读:
    jdk .tar.gz 包安装 inAction
    Consistent Hashing原理与实现
    开放GitHub的理由
    dll signing issue
    Regular expression cheat sheet
    DOMElement之Offset
    扫码支付测试点
    SQL注入是什么?如何防止?
    什么是接口测试?为什么要做接口测试?如何开展接口测试?
    软件测试的常识
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9575449.html
Copyright © 2011-2022 走看看