Codeforces Round #365 (Div. 2) C

 1 // Codeforces Round #365 (Div. 2)
 2 // C - Chris and Road 二分找切点
 3 // 题意:给你一个凸边行,凸边行有个初始的速度往左走,人有最大速度,可以停下来,竖直走。
 4 // 问走到终点的最短时间
 5 // 思路:
 6 // 1.贪心来做
 7 // 2.我觉的二分更直观
 8 // 可以抽象成:一条射线与凸边行相交,判断交点。二分找切点
 9 
10 #include <bits/stdc++.h>
11 using namespace std;
12 #define LL long long
13 const int inf = 0x3f3f3f3f;
14 const int MOD =998244353; 
15 const int N =1e6+10; 
16 #define clc(a,b) memset(a,b,sizeof(a))
17 const double eps = 1e-7;
18 struct Point{
19     double x,y;
20     Point(){}
21     Point(int x_,int y_):x(x_),y(y_){}
22     Point operator + (const Point &t)const{
23         return Point(x+t.x,y+t.y);
24     }
25     Point operator - (const Point &t)const{
26         return Point(x-t.x,y-t.y);
27     }
28     double operator * (const Point &t)const{
29         return x*t.y-y*t.x;
30     }
31     double operator ^ (const Point &t)const{
32         return x*t.x+y*t.y;
33     }
34     bool operator < (const Point & a) const{
35         if(x==a.x) return y>a.y;
36         return x<a.x;
37     }
38 }p[10010];
39 
40 int n;
41 bool judge(double k,double b){
42     int tot=0,cnt=0;
43     for(int i=1;i<=n;i++){
44         if(k*p[i].x+b-p[i].y<0) tot++;
45         else cnt++;
46         if(cnt&&tot) return false;
47     }
48     return true;
49 }
50 int main(){
51     int w;
52     double v,u;
53     scanf("%d%d%lf%lf",&n,&w,&v,&u);
54     for(int i=1;i<=n;i++){
55         scanf("%lf%lf",&p[i].x,&p[i].y);
56     }
57     double k=u/v;
58     if(judge(k,0.0)){
59         printf("%.8f
",(double)(w/u));
60     }
61     else{
62         double l=0,r=1e9;
63         double ans;
64         while(r-l>eps){
65              double mid = (l+r)/2.0;
66              if(judge(k,-mid/v*u)){
67                 ans=(double)(w/u)+mid/v;
68                 r=mid;
69              }
70              else{
71                 l=mid;
72              }
73         }
74         printf("%.8f
",ans);
75     }
76     return 0;
77 }
原文地址:https://www.cnblogs.com/ITUPC/p/5767900.html