【SCOI 2010】传送带

为了方便,我们不妨设$\rm P \lt Q,R$

我们发现,有$\rm E$点在$\rm AB$上,$\rm F$点在$\rm CD$上,最优解一定是$\rm AE\rightarrow EF\rightarrow FD$,因为若中途离开某个传送带再回来,显然是不优的。

考虑固定点$E$,观察点$F$对答案造成的影响。

作过点$\rm E$作$\rm EG \perp CD$。

若$\rm F$在$\rm CG$上,单调性很显然。

若$\rm F$在$\rm GD$上,朝$\rm D$移动时。

  由于$\rm |FD|$在减少,而$\rm |EF|$在增加,且越增加越快,所以$\rm |FD| + |EF|$会先减少,后增加。

所以当$\rm E$点固定的时候,$\rm AE\rightarrow EF\rightarrow FD$的长度是个凹的单峰函数,我们可以用三分解决。

我们可以先三分$E$,再三分$F$来解决这题。什么?证明?我真的不会。

至于三分的时候怎么选坐标,可以按照端点横坐标纵坐标直接取$\frac{1}{3}$。

比如下图我们要找到$\rm CB$的$\frac{1}{3}$处,直接是$\rm B$和$\rm C$横坐标纵坐标分别三分之一即可。

明显有$\rm \triangle ABC\sim \triangle BDE$

所以$\rm D$点也在线段的$\frac{1}{3}$

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const double eps = 1e-6;
 6 
 7 double x[4], y[4], p, q, r;
 8 
 9 double dist(double xa, double ya, double xb, double yb) {
10     return sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb));
11 }
12 
13 double check(double ex, double ey) {
14     double lx = x[2], ly = y[2], rx = x[3], ry = y[3];
15     while(fabs(rx - lx) > eps || fabs(ry - ly) > eps) {
16         double m1x = lx + (rx - lx) / 3, m1y = ly + (ry - ly) / 3, 
17                m2x = rx - (rx - lx) / 3, m2y = ry - (ry - ly) / 3;
18         if(dist(ex, ey, m1x, m1y) / r + dist(m1x, m1y, x[3], y[3]) / q <
19            dist(ex, ey, m2x, m2y) / r + dist(m2x, m2y, x[3], y[3]) / q)
20             rx = m2x, ry = m2y;
21         else lx = m1x, ly = m1y;
22     }
23     return dist(ex, ey, lx, ly) / r + dist(lx, ly, x[3], y[3]) / q;
24 }
25 
26 int main() {
27     for(int i = 0; i < 4; i++) cin >> x[i] >> y[i];
28     cin >> p >> q >> r;
29     double lx = x[0], ly = y[0], rx = x[1], ry = y[1];
30     while(fabs(rx - lx) > eps || fabs(ry - ly) > eps) {
31         double m1x = lx + (rx - lx) / 3, m1y = ly + (ry - ly) / 3, 
32                m2x = rx - (rx - lx) / 3, m2y = ry - (ry - ly) / 3;
33         if(dist(x[0], y[0], m1x, m1y) / p + check(m1x, m1y) <
34            dist(x[0], y[0], m2x, m2y) / p + check(m2x, m2y))
35             rx = m2x, ry = m2y;
36         else lx = m1x, ly = m1y;
37     }
38     printf("%.2lf\n", dist(x[0], y[0], lx, ly) / p + check(lx, ly));
39     return 0;
40 }
View Code

 

posted @ 2018-08-23 07:57  zhylj  阅读(306)  评论(0编辑  收藏  举报