zoukankan      html  css  js  c++  java
  • 1439:【SCOI2010】传送带

    1439:【SCOI2010】传送带(一本通网站原题链接)

    【分析】

      这个题目其实我想的比较简单,问题的决策点在于何时离开第一个传送带,何时上第二个传送带。两个决策点可变为一个决策问题用两次。我们把这个问题换一个说法。你在笔直的河岸边发现河中一人求救,己知你水中速度和岸上速度,求你到达求救者的最短时间。那这个决策就是你在何处下水。这问题用一个极限思考:河岸看作足够长,在河岸的两端入水,到达时间都是很大,当向中点某点靠近时,这个时间在缩小。换言之,把河岸看作一个坐标轴,入水点与你所在位置的差为自变量x,那函数值时间t是x的一个函数,这个函数的单调性为先减后增型(实质是一个单峰函数),那解决它的办法就是三分法。回到本题,我们的策略可以这样描述:先把第一个传送带三分,分点分别为A、B。选择A还是B那将取决于从哪里下传送带更快。这个快与慢还需要第二次决策:从哪里上第二个传送带。我们可以先用三分法算出从A下传送带的最快时间,同样三分法算出从B下传送带的最快时间,那我们就知道A、B两点我们选择哪一点了。接着就是把A、B的距离无限靠近就好。注意,本题有一个特殊情形,我们的思路是两个三分法嵌套,外层最好用do循环,否则外层中传送带长度为0直接就不进入循环了

    【AC代码】

      (说明:为了熟悉下结构体重载,我选择了用结构体,具体实现方法因你而改变)

    //1439:【SCOI2010】传送带 
    #include<iostream>
    #include<cmath>
    #include<iomanip>
    using namespace std;
    struct point{
        double x,y;
        void operator = (const point p) {
            //point t;
        x=p.x;
        y=p.y;
        //return t;
        }
        point operator * (const int n) {
            point t;
        t.x=x*n,t.y=y*n;
        return t;
        }
        point operator / (const int n) {
            point t;
        t.x=x/n,t.y=y/n;
        return t;
        }
        point operator +(const point  p)
        {
            point t;
            t.x=x+p.x,t.y=y+p.y;
        return t;
        }
    }a[4],b[4],md[4];
    double q,p,r;
    double dis(point w,point e)
    {
        double h,v,s;
        h=w.x-e.x;
        v=w.y-e.y;
        s=sqrt(h*h+v*v);
        //cout<<w.x<<' '<<w.y<<' '<<e.x<<' '<<e.y<<' '<<s<<endl;
        return s;
    }
    double jl(int m,int n)
    {
        double s=0;
        s+=dis(a[0],md[m])/p;
        s+=dis(md[m],md[n])/r;
        s+=dis(md[n],a[3])/q;
        return s;
    }
    void pr(point w)
    {
        cout<<w.x<<' '<<w.y<<endl;
    }
    int main(){
        for(int i=0;i<4;i++)cin>>a[i].x>>a[i].y;
        cin>>p>>q>>r;
        b[0]=a[0],b[1]=a[1];
        do
        {
            md[0]=(b[0]*2+b[1])/3;
            md[1]=(b[0]+b[1]*2)/3;
            b[2]=a[2],b[3]=a[3];
            while(dis(b[2],b[3])>1e-11)
            {
                md[2]=(b[2]*2+b[3])/3;
                md[3]=(b[2]+b[3]*2)/3;
                if(jl(0,2)<jl(0,3))b[3]=md[3];
                else b[2]=md[2];
            }
            if(jl(0,3)<jl(1,3))b[1]=md[1];
            else b[0]=md[0];
        }while(dis(b[0],b[1])>1e-11);
        cout<<fixed<<setprecision(2)<<jl(0,2);
        return 0;
    }
  • 相关阅读:
    Hashcode的作用
    java 强弱软虚 四种引用,以及用到的场景
    Object类有哪些公用方法?
    equals和==的区别
    switch能否用string做参数
    Java九种基本数据类型,以及他们的封装类
    Singleton(Java)
    快速排序和二分查找(Javascript)
    快速排序和二分查找(Go)
    ubuntn 安装 MySQL
  • 原文地址:https://www.cnblogs.com/wendcn/p/12639871.html
Copyright © 2011-2022 走看看