zoukankan      html  css  js  c++  java
  • 【二分】【半平面交】Gym

    发现炸毁的瞭望塔必然是连续的,其余下的部分是一个半平面。

    二分答案,枚举所有可能的炸毁情况,做个半平面交,如果交出来面积是0,就可以保证不存在安全区域。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define EPS 0.0000001
    #define N 50010
    typedef double db;
    const db PI=acos(-1.0);
    struct Point{db x,y;};
    typedef Point Vector;
    Vector operator - (const Point &a,const Point &b){return (Vector){a.x-b.x,a.y-b.y};}
    Vector operator * (const Vector &a,const db &k){return (Vector){a.x*k,a.y*k};}
    Vector operator + (const Vector &a,const Vector &b){return (Vector){a.x+b.x,a.y+b.y};}
    db Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    struct Line
    {
        Point p; Vector v; db ang;
        Line(){}
        Line(const Point &a,const Point &b)
          {
            v=b-a;
            p=a;
            ang=atan2(v.y,v.x);
            if(ang<0) ang+=2.0*PI;
          }
    };
    bool operator < (const Line &a,const Line &b){return a.ang<b.ang;}
    bool OnLeft(Line l,Point a){return Cross(l.v,a-l.p)>0;}
    Point GetJiaodian(Line a,Line b){return a.p+a.v*(Cross(b.v,a.p-b.p)/Cross(a.v,b.v));}
    int n;
    Point ps[N];
    Line q[N];
    Line ls[N];
    int nn;
    Point a[N];
    #define INF 10000000000.0
    bool BPMJ(int x)
    {
    	int head=1,tail=1;
    	n=0;
    	memset(q,0,sizeof(q));
    	memset(ps,0,sizeof(ps));
    	for(int i=nn;i>=x+2;--i){
    		ls[++n]=Line(a[i],a[i-x-1]);
    	}
    	for(int i=x+1,j=0;i>=1;++j,--i){
    		ls[++n]=Line(a[i],a[nn-j]);
    	}
    //    ls[++n]=Line((Point){INF,INF},(Point){-INF,INF});
    //    ls[++n]=Line((Point){-INF,INF},(Point){-INF,-INF});
    //    ls[++n]=Line((Point){-INF,-INF},(Point){INF,-INF});
    //    ls[++n]=Line((Point){INF,-INF},(Point){INF,INF});
        sort(ls+1,ls+n+1);
        q[1]=ls[1];
        for(int i=2;i<=n;++i)
          {
            while(head<tail&&(!OnLeft(ls[i],ps[tail-1]))) --tail;
            while(head<tail&&(!OnLeft(ls[i],ps[head]))) ++head;
            q[++tail]=ls[i];
            if(fabs(Cross(q[tail].v,q[tail-1].v))<EPS)
              {
                --tail;
                if(OnLeft(q[tail],ls[i].p))
                  q[tail]=ls[i];
              }
            if(head<tail)
              ps[tail-1]=GetJiaodian(q[tail-1],q[tail]);
          }
        while(head<tail&&(!OnLeft(q[head],ps[tail-1]))) --tail;
        if(tail-head<=1){
        	return 1;
        }
        ps[tail]=GetJiaodian(q[tail],q[head]);
        return head>tail;
    }
    int main()
    {
    	freopen("jungle.in","r",stdin);
    	freopen("jungle.out","w",stdout);
        scanf("%d",&nn);
        for(int i=1;i<=nn;++i) scanf("%lf%lf",&a[i].x,&a[i].y);
        int l=1,r=nn-2;
        while(l<r){
        	int mid=(l+r>>1);
        	if(BPMJ(mid)){
        		r=mid;
        	}
        	else{
        		l=mid+1;
        	}
        }
        printf("%d
    ",l);
        return 0;
    }
  • 相关阅读:
    Microsoft Dynamics CRM 2011 配置好的IFD环境 怎么制作证书?
    Microsoft Dynamics CRM 2011 Plugin中PluginExecutionContext.InputParameters["Target"]中的Target是从哪来的?
    编程写一个方法时,注意方法中传参数的数量最好不要超过5个,超过5个怎么办?可以用struct或class,或一个字典类
    Microsoft Dynamics CRM 2011 常用JS 按F12 改动窗体上数据的方法
    JS 实现轮播图
    JS晃动的花朵
    定时器的应用 盒子的移动
    JavaScript 经典实例
    累加 9*9乘法表 阶乘
    函数方法
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7159679.html
Copyright © 2011-2022 走看看