zoukankan      html  css  js  c++  java
  • 【计算几何】【凸包】【极角排序】【二分】Gym

    平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内。

    对红点求凸包后,转化为询问有多少个黑点在凸包内。

    点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后,使用二分法就可以判定点在哪个剖分出来的三角形的夹角内,然后用叉积即可判定其在凸包内还是外,O(logn):

    http://www.cnblogs.com/dream-wind/archive/2012/05/23/2514694.html

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    int n,m,K,O;
    struct Point{
    	ll x,y;
    	double jiao;
    	Point(){}
    	Point(const ll &x,const ll &y){
    		this->x=x;
    		this->y=y;
    	}
    	void Read(){
    		scanf("%lld%lld",&x,&y);
    	}
    };
    typedef Point Vector;
    Point p0,p;
    Vector operator - (const Point &a,const Point &b){
    	return Vector(a.x-b.x,a.y-b.y);
    }
    ll Cross(const Vector &a,const Vector &b){
    	return a.x*b.y-a.y*b.x;
    }
    bool cmp(const Point &a,const Point &b){
    	return a.x!=b.x ? a.x<b.x : a.y<b.y;
    }
    bool cm2(const Point &a,const Point &b){
    	return a.jiao<b.jiao;
    }
    Point ps[10010],qs[10010];
    bool check(int mid){
    	return Cross(qs[mid]-p0,p-p0)<=0;
    }
    int main(){
    //	freopen("j.in","r",stdin);
    	scanf("%d",&n);
    	for(int i=0;i<n;++i){
    		ps[i].Read();
    	}
    	sort(ps,ps+n,cmp);
    	for(int i=0;i<n;++i){
    		while(K>1 && Cross(qs[K-1]-qs[K-2],ps[i]-qs[K-1])<=0){
    			--K;
    		}
    		qs[K++]=ps[i];
    	}
    	for(int i=n-2,t=K;i>=0;--i){
    		while(K>t && Cross(qs[K-1]-qs[K-2],ps[i]-qs[K-1])<=0){
    			--K;
    		}
    		qs[K++]=ps[i];
    	}
    	--K;
    	for(int i=1;i<K;++i){
    		if(qs[i].y<qs[O].y || (qs[i].y==qs[O].y && qs[i].x<qs[O].x)){
    			O=i;
    		}
    	}
    	p0=qs[O];
    	for(int i=0;i<K;++i){
    		qs[i].jiao=atan2((double)(qs[i].y-qs[O].y),(double)(qs[i].x-qs[O].x));
    	}
    	for(int i=O;i<K-1;++i){
    		qs[i]=qs[i+1];
    	}
    	--K;
    	sort(qs,qs+K,cm2);
    	scanf("%d",&m);
    	int ans=0;
    	for(int i=1;i<=m;++i){
    		p.Read();
    		if(Cross(p-p0,qs[0]-p0)<=0 && Cross(p-p0,qs[K-1]-p0)>=0){
    			int l=1,r=K-1;
    			while(l<r){
    				int mid=(l+r>>1);
    				if(check(mid)){
    					r=mid;
    				}
    				else{
    					l=mid+1;
    				}
    			}
    			if(Cross(p-qs[l-1],qs[l]-qs[l-1])<=0){
    				++ans;
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    react树节点异步加载和拖拽生成节点
    基于hook的ant design 的tab页的删除功能实现
    dva在hook里effect异步获取数据不同步问题
    SpringBoot整合Rredis
    SpringBoot实现Session共享
    SpringBoot整合Mybatis
    SpringBoot整合JPA多数据源
    SpringData关键字查询方法和自定义查询方法
    SpringBoot整合Mybatis多数据源
    jdbctemplate配置多数据源
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7296653.html
Copyright © 2011-2022 走看看