1. 程式人生 > >牛客第二場 C.message(計算幾何+二分)

牛客第二場 C.message(計算幾何+二分)

題目傳送:https://www.nowcoder.com/acm/contest/140/C

題意:有n個雲層,每個雲層可以表示為y=ax+b。每個飛機的航線可以表示為時間x時,座標為(x,cx+d)。問飛機旅程與最後一個雲層相交的x座標。不存在

分析:

可以確定兩直線聯立後解得交點x=(b-d)/(a-c)。

可以看做是點(a,b)和(c,d)的斜率的負數。

要求的最大的x,那麼就變成了求得最小的斜率,答案最後再乘-1即可。

 

就是求每個(c,d)點到(a,b)的斜率,可以把每一個(a,b)看成一個點,求凸包。

每碰到一個(c,d)二(san)分到凸包上的點的斜率。維護最小值。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const double eps=1e-8;
  4 const double inf=1e20;
  5 const int maxn=1e5+10;
  6 int sgn(double x){
  7     if (fabs(x)<eps) return 0;
  8     if (x<0) return -1;
  9     return 1;
 10 }
 11 struct point{
 12     double x,y;
 13     int
id; double ans; 14 point(){} 15 point(double _x,double _y):x(_x),y(_y){} 16 point operator +(const point &b)const{ 17 return point(x+b.x,y+b.y); 18 } 19 point operator -(const point &b)const{ 20 return point(x-b.x,y-b.y); 21 } 22 double operator
^(const point &b)const{ 23 return x*b.y-y*b.x; 24 } 25 bool operator <(const point &b)const{ 26 if (sgn(x-b.x)==0) return y<b.y; 27 return x<b.x; 28 } 29 }; point p[maxn],pp[maxn]; 30 int n,m; 31 double calc(point a,point b){ 32 if (sgn(a.x-b.x)==0) return 1.0; 33 return (a.y-b.y)/(a.x-b.x); 34 } 35 double cross(point p,point a,point b){ 36 return (a-p)^(b-p); 37 } 38 void convex_hull(point p[],int N,point q[]){ 39 sort(p,p+N); 40 int m=0; 41 for (int i=0;i<N;i++){ 42 if (p[i].id>n){ 43 if (m==0) continue; 44 int l=0,r=m-1,mid; 45 while (l<r){ 46 mid=(l+r)>>1; 47 if (calc(p[i],q[mid])<calc(p[i],q[mid+1])){ 48 l=mid; 49 } 50 else r=mid-1; 51 } 52 p[i].ans=min(p[i].ans,calc(p[i],q[l])); 53 } 54 else{ 55 while (m>1 && cross(q[m-2],q[m-1],p[i])<=0) m--; 56 q[m++]=p[i]; 57 } 58 } 59 int k=m; 60 for (int i=N-2;i>=0;i--){ 61 if (p[i].id>n){ 62 if (m==k) continue; 63 int l=0,r=m-1,mid; 64 while (l<r){ 65 mid=(l+r)>>1; 66 if (calc(p[i],q[mid])<calc(p[i],q[mid+1])){ 67 l=mid; 68 } 69 else r=mid-1; 70 } 71 p[i].ans=min(p[i].ans,calc(p[i],q[l])); 72 } 73 else{ 74 while (m>k && cross(q[m-2],q[m-1],p[i])<=0) m--; 75 q[m++]=p[i]; 76 } 77 } 78 } 79 bool cmp(point a,point b){ 80 return a.id<b.id; 81 } 82 int main(){ 83 cin >> n; 84 for (int i=0;i<n;i++){ 85 cin >> p[i].x >> p[i].y; 86 p[i].id=i+1; p[i].ans=inf; 87 } 88 cin >> m; 89 for (int i=n;i<n+m;i++){ 90 cin >> p[i].x >> p[i].y; 91 p[i].id=i+1; p[i].ans=inf; 92 } 93 convex_hull(p,n+m,pp); 94 for (int i=0;i<n+m;i++){p[i].x*=-1; p[i].y*=-1;} 95 convex_hull(p,n+m,pp); 96 sort(p,p+n+m,cmp); 97 for (int i=n;i<n+m;i++) 98 if (p[i].ans>=0) cout << "No cross\n"; 99 else printf("%.7f\n",-p[i].ans); 100 return 0; 101 }