BZOJ1857[SCOI2010]传送带

题目大意:平面上两条线段,一个人从一条线段的一个点到另一条线段的一个点,最小时间是多少

路径肯定是在一条线段上走一段,然后走平面,最后再走另一条线段,那么需要确定的就是在两条线段上走的距离,其他暴力算就行了

一条线段距离的确定直接三分就好了,另一条嘛,再套个三分就好了

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
    double x,y;
}A[4];
node v1,v2;
double P,Q,R;
double dis(double x1,double y1,double x2,double y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double get_dis(double l1,double l2){
    double x1,x2,y1,y2;
    x1=A[0].x+v1.x*l1;y1=A[0].y+v1.y*l1;
    x2=A[3].x+v2.x*l2;y2=A[3].y+v2.y*l2;
    return dis(A[0].x,A[0].y,x1,y1)/P+dis(x1,y1,x2,y2)/R+dis(x2,y2,A[3].x,A[3].y)/Q;
}
double get(double l1){
    double L=0,R=1,mid1,mid2;
    for(int i=1;i<=200;++i){
        mid1=(L+R)/2,mid2=(mid1+R)/2;
        double k1=get_dis(l1,mid1);
        double k2=get_dis(l1,mid2);
        if(k1<k2)R=mid2;else L=mid1;
    }
    return get_dis(l1,L);
}
void work(){
    for(int i=0;i<4;++i)scanf("%lf%lf",&A[i].x,&A[i].y);
    scanf("%lf%lf%lf",&P,&Q,&R);
    v1.x=A[1].x-A[0].x,v1.y=A[1].y-A[0].y;
    v2.x=A[2].x-A[3].x,v2.y=A[2].y-A[3].y;
    double L=0,R=1,mid1,mid2;
    for(int i=1;i<=200;++i){
        mid1=(L+R)/2,mid2=(mid1+R)/2;
        double k1=get(mid1);
        double k2=get(mid2);
        if(k1<k2)R=mid2;else L=mid1;
    }
    printf("%.2lf\n",get(L));
}
int main(){
    work();
    return 0;
}
View Code

 

posted @ 2016-04-01 06:19  117208  阅读(204)  评论(0编辑  收藏  举报