• BZOJ 1857: [Scoi2010]传送带(三分套三分)


    Time Limit: 1 Sec Memory Limit: 64 MB
    Submit: 2549 Solved: 1370
    [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

    思路

    大概算是三分的模板题

    在线段AB和线段CD分别选一个点E,F。假设所需的最短时间的路径为:A->E->F->D

    然后单独拿出来E->F->D这条路径,将F->D这条路缩成一个点,再将E->F->D这条路径缩成一个点,计算A点到E点的花费时间,再加上E->F->D路径所花费的最短时间即可

    可以知道(并不知道),E点到F->D这个距离花费随着E点坐标的变化,是一个凸函数的函数关系,A点到E->F->D也是一个凸函数(证明看这里:戳我戳我

    所以我们可以先假设E点已经找到,然后线段CD上三分寻找F点的位置,使得E->F->D的花费最小

    然后在线段AB上三分E点的位置,最后将两段的花费加起来就是最小的花费。

    代码

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define ms(a,b) memset(a,b,sizeof(a))
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=1e6+10;
    const int mod=1e9+7;
    const int maxm=1e3+10;
    const double eps=1e-8;
    using namespace std;
    struct point
    {
        double x,y;
    };
    point a,b,c,d;
    double P,Q,R;
    inline double dis(point a,point b)
    {
        double dx=a.x-b.x;
        double dy=a.y-b.y;
        return sqrt(dx*dx+dy*dy);
    }
    inline double F(point E,point F)
    {
        return dis(E,F)/R+dis(F,d)/Q;
    }
    inline double sanfen(point E,point l,point r)
    {
        point mid,midr;
        while(dis(l,r)>eps)
        {
            mid.x=(l.x+r.x)/2;
            mid.y=(l.y+r.y)/2;
            midr.x=(mid.x+r.x)/2;
            midr.y=(mid.y+r.y)/2;
            if(F(E,mid)>F(E,midr))
                l.x=mid.x,l.y=mid.y;
            else
                r.x=midr.x,r.y=midr.y;
        }
        return F(E,l);
    }
    inline double solve(point l,point r)
    {
        point mid,midr;
        while(dis(l,r)>eps)
        {
            mid.x=(l.x+r.x)/2;
            mid.y=(l.y+r.y)/2;
            midr.x=(mid.x+r.x)/2;
            midr.y=(mid.y+r.y)/2;
            double ans1=dis(a,mid)/P+sanfen(mid,c,d);
            double ans2=dis(a,midr)/P+sanfen(midr,c,d);
            if(ans1>ans2)
                l.x=mid.x,l.y=mid.y;
            else
                r.x=midr.x,r.y=midr.y;
        }
        return dis(a,l)/P+sanfen(l,c,d);
    }
    int main(int argc, char const *argv[])
    {
        #ifndef ONLINE_JUDGE
            freopen("/home/wzy/in.txt", "r", stdin);
            freopen("/home/wzy/out.txt", "w", stdout);
            srand((unsigned int)time(NULL));
        #endif
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>a.x>>a.y>>b.x>>b.y;
        cin>>c.x>>c.y>>d.x>>d.y;
        cin>>P>>Q>>R;
        cout<<fixed<<setprecision(2)<<solve(a,b)<<endl;
        #ifndef ONLINE_JUDGE
            cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl;
        #endif
        return 0;
    }
    
  • 相关阅读:
    SQL Server 2005存储过程示例
    SQL Server 存储过程
    SQL Server 2005存储过程示例
    转正申请书
    SQL注入天书
    转:毕业半年,我是如何从一名程序员成长为一名项目经理
    DIMFOM
    MONSA
    GLOBSYMM
    MASSHA
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11558478.html
Copyright © 2020-2023  润新知