极角排序+双指针——uva11704

极角排序双指针扫描时一定要把数组扩展成两倍!这样写起来方便很多(惨痛教训)

#include<bits/stdc++.h>
using namespace std;
#define N 200005
typedef double db;
const db eps=1e-8;
const db pi=acos(-1);
int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;}
int cmp(db k1,db k2){return sign(k1-k2);}

struct point{
    db x,y;
    int flag;
    point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    point operator * (db k1) const{return (point){x*k1,y*k1};}
    point operator / (db k1) const{return (point){x/k1,y/k1};}    
    int getP() const {return sign(y)==1 || (sign(y)==0&&sign(x)>=0);}
};
db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
int comp(point k1,point k2){
    if(k1.getP()==k2.getP())return sign(cross(k1,k2))>0;
    return k1.getP()<k2.getP();
}

point p[N];
int n,m;

int main(){
    while(cin>>n>>m && n>=0){
        if(n==-1)break;
        
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            p[i].flag=0;
        }
        for(int i=1;i<=m;i++){
            scanf("%lf%lf",&p[i+n].x,&p[i+n].y);
            p[i+n].flag=1;
        }
        sort(p+1,p+1+n+m,comp);
        for(int i=1;i<=n+m;i++)p[i+n+m]=p[i];
        
        int pos=1,num0=0,num1=0,flag=0;
        if(p[1].flag)num1++;
        else num0++;
        
        for(int i=1;i<=n+m;i++){
            while(pos+1<n+m+i && sign(cross(p[i],p[pos+1]))>=0){
                pos++;
                if(p[pos].flag==0)num0++;
                else num1++;
            }
            
            if(num0*2==n && num1*2==m)flag=1;
            
            if(p[i].flag)num1--;
            else num0--;
        }    
        if(flag)puts("YES");
        else puts("NO");
    }
}
/*
4 4
1 2
1 3
1 4
1 5
2 1
3 1
4 1
5 1
*/

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12335821.html