BZOJ1857:[SCOI2010]传送带(三分套三分)
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
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
Solution
设(A,B)上有一点E,(C,D)上有一点F,那么最优方案肯定是A->E->F->D。发现E和F的位置是两个单峰函数,然后三分套个三分就可以过了_(:зゝ∠)_
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 using namespace std; 7 8 int Ax,Ay,Bx,By,Cx,Cy,Dx,Dy,P,Q,R; 9 double eps=1e-8; 10 11 double cost(double x,double y,double p,double q,double v) 12 { 13 return sqrt((p-x)*(p-x)+(q-y)*(q-y))/v; 14 } 15 16 double calc(double x,double y,double p,double q) 17 { 18 return cost(Ax,Ay,x,y,P)+cost(x,y,p,q,R)+cost(p,q,Dx,Dy,Q); 19 } 20 21 double work2(double x,double y) 22 { 23 double lx=Cx,ly=Cy,rx=Dx,ry=Dy; 24 double lmidx,rmidx,lmidy,rmidy,ans1,ans2; 25 while(fabs(rx-lx)>eps || fabs(ry-ly)>eps) 26 { 27 lmidx=lx+(rx-lx)/3.0; 28 rmidx=lx+((rx-lx)/3.0)*2.0; 29 lmidy=ly+(ry-ly)/3.0; 30 rmidy=ly+((ry-ly)/3.0)*2.0; 31 ans1=calc(x,y,lmidx,lmidy); 32 ans2=calc(x,y,rmidx,rmidy); 33 if(ans1>ans2)lx=lmidx,ly=lmidy; 34 else rx=rmidx,ry=rmidy; 35 } 36 return (max(calc(x,y,lx,ly),calc(x,y,rx,ry))); 37 } 38 39 double work1() 40 { 41 double lx=Ax,ly=Ay,rx=Bx,ry=By; 42 double lmidx,rmidx,lmidy,rmidy,ans1,ans2; 43 while(fabs(rx-lx)>eps || fabs(ry-ly)>eps) 44 { 45 lmidx=lx+(rx-lx)/3.0; 46 rmidx=lx+((rx-lx)/3.0)*2.0; 47 lmidy=ly+(ry-ly)/3.0; 48 rmidy=ly+((ry-ly)/3.0)*2.0; 49 ans1=work2(lmidx,lmidy); 50 ans2=work2(rmidx,rmidy); 51 if(ans1>ans2)lx=lmidx,ly=lmidy; 52 else rx=rmidx,ry=rmidy; 53 } 54 return (max(work2(lx,ly),work2(rx,ry))); 55 } 56 57 int main() 58 { 59 scanf("%d%d%d%d",&Ax,&Ay,&Bx,&By); 60 scanf("%d%d%d%d",&Cx,&Cy,&Dx,&Dy); 61 scanf("%d%d%d",&P,&Q,&R); 62 printf("%.2lf\n",work1()); 63 }