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; }