BZOJ1811:[Ioi2005]mea 乱搞
BZOJ1345:[Baltic2007]序列问题Sequence 乱搞

BZOJ1857:[Scoi2010]传送带 三分

shinbokuow posted @ Jan 15, 2015 10:19:05 AM in BZOJ with tags 三分 , 1260 阅读

思路:

显然一条比较优的路径是从\(A\)走到\(AB\)上一点\(X\),然后从\(X\)走到\(CD\)上一点\(Y\),然后从\(Y\)走到\(D\).

关键是\(X,Y\)如何确定.

我们能够发现\(X\)点确定时,随着\(Y\)的移动,总路程是一个单峰函数.

更加神奇的是,随着\(X\)的移动,通过我们上述三分得到的总路程也是一个单峰函数!

没什么说的,三分套三分就行了.

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
 
typedef double f2;
 
#define eps 1e-8
struct Point{
    f2 x,y;
    void read(){scanf("%lf%lf",&x,&y);}
    Point(){}
    Point(f2 _x,f2 _y):x(_x),y(_y){}
    Point operator-(const Point&B)const{return Point(B.x-x,B.y-y);}
    Point operator+(const Point&B)const{return Point(x+B.x,y+B.y);}
    Point operator*(const f2&p)const{return Point(p*x,p*y);}
}A,B,C,D;
 
int vab,vcd,vplane;
 
f2 sqr(const f2&x){return x*x;}
f2 Dist(const Point&A,const Point&B){return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));}
f2 f(Point x,Point l,Point v,f2 k){
    return Dist(x,l+v*k)/vplane+Dist(l+v*k,l+v)/vcd;
}
f2 Solve(Point x,Point l,Point r){
    Point v=l-r;
    f2 L=0,R=1,LL,RR,ansl,ansr,lastans=1e12,nowans;
    while(1){
        LL=L+(R-L)/3,RR=R-(R-L)/3;
        ansl=f(x,l,v,LL),ansr=f(x,l,v,RR);
        if(ansl<ansr)R=RR,nowans=ansl;else L=LL,nowans=ansr;
        if(fabs(nowans-lastans)<1e-5)break;lastans=nowans;
    }
    return lastans;
}
 
int main(){
    A.read(),B.read(),C.read(),D.read();
    scanf("%d%d%d",&vab,&vcd,&vplane);
    f2 L=0,R=1,LL,RR,ansl,ansr,lastans=1e12,nowans;Point v=A-B;
    while(1){
        LL=L+(R-L)/3,RR=R-(R-L)/3;
        ansl=Dist(A,A+v*LL)/vab+Solve(A+v*LL,C,D),ansr=Dist(A,A+v*RR)/vab+Solve(A+v*RR,C,D);
        if(ansl<ansr)R=RR,nowans=ansl;else L=LL,nowans=ansr;
        if(fabs(nowans-lastans)<1e-5)break;lastans=nowans;
    }
    printf("%.2lf",lastans);
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter