luogu P2571 [SCOI2010]传送带

传送门

Time cost:65min

莫名想起Slay

由于速度不一定而且线段位置关系乱七八糟的 所以并不能直接做垂

实在懒得想? 暴搜啊!

枚举两条线上离开的点计算长度

中间那个线段的端点就叫离开的点了!(AB上的记为E,CD上的记为F)

打个表发现是单峰?

推一下证明:

在AB上的点E确定的时候

随着F在CD上位置的改变,ED的长度先小后大,DF的长度不断增大

所以加权之后折线EDF的长度是一个单峰函数(有最小值)

同时 对于AB上的每一个E 对应的EDF最小值也是先小后大

(这个分个情况或者求个导 就能算出来)

又是一个单峰函数 再三分

数据范围也不大 复杂度O(nlg2n)? 反正肯定能过

就是计算几何的东西......struct和那个比例转化成长度及其e心

不说了上代码

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<iostream>
 5 #define eps 1e-9
 6 using namespace std;
 7 typedef double D;
 8 int n;
 9 D p,q,r;
10 struct Point{
11     D x,y;
12     Point(){}
13     Point(D _x,D _y) {
14     x = _x,y = _y;
15     }
16     Point operator + (const Point &o) const {
17     return Point(x+o.x,y+o.y);
18     }
19     void input() {
20     scanf("%lf%lf",&x,&y);
21     }
22 }a,b,c,d,e,f;
23 
24 struct Line{
25     Point a,b;
26     D dx,dy,s,c,l;
27     Line(){}
28     Line(Point _a,Point _b){
29     a = _a,b = _b;
30     dy = b.y - a.y,dx = b.x - a.x;
31     l = sqrt(dx * dx + dy * dy);
32     s = dy / l,c = dx / l;
33     }
34 }ab,cd,ef;
35 Point Cross(Line a,D b) {
36     if(!a.l) return a.a;
37     return Point(a.a.x + b * a.c , a.a.y + b * a.s);
38 }
39 
40 D Check(D x) {
41     f = Cross(cd,x);
42     ef = Line(e,f);
43     return ef.l / q + (cd.l - x) / r;
44 }
45 
46 D check(D x) {
47     e = Cross(ab,x);
48     D L = 0,R = cd.l;
49     while(R - L >= eps) {
50     D m = (L+R) / 2.0;
51     if(Check(m + eps) - Check(m - eps) > 0) R = m;
52     else L = m;
53     }
54     return x / p + Check(L);
55 }
56 
57 int main() {
58     a.input(),b.input(),c.input(),d.input();
59     ab = Line(a,b),cd = Line(c,d);
60     scanf("%lf%lf%lf",&p,&r,&q);
61     D L = 0.0,R = ab.l;
62     while(R - L >= eps) {
63     D m = (L+R) / 2.0;
64     if(check(m+eps) - check(m-eps) > 0) R = m;
65     else L = m;
66     }
67     printf("%.2f
",check(L));
68     return 0;
69 }
View Code
> 别忘了 总有人在等着你
原文地址:https://www.cnblogs.com/yuyanjiaB/p/9811774.html