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

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 }
posted @ 2018-09-11 15:05  Refun  阅读(166)  评论(0编辑  收藏  举报