zoukankan      html  css  js  c++  java
  • 牛客第二场 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
    ";
     99         else printf("%.7f
    ",-p[i].ans);
    100     return 0;
    101 } 
  • 相关阅读:
    CCD类型介绍:Linear, Interline, FullFrame, FrameTransfer CCD的区别
    电源纹波调试小结
    FPGA调试之特殊管脚
    C#获取指定日期的星期,和sql server中根据指定日期取出来的相对应
    利用TSQL添加作业
    SQL insert失败时也会造成自增长字段加1
    ANSI编码
    分页
    PHP编码转换
    SqlDataReader读取带有输出参数的存储过程
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/9826332.html
Copyright © 2011-2022 走看看