极角排序双指针扫描时一定要把数组扩展成两倍!这样写起来方便很多(惨痛教训)
#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 */