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 }