1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| #include<cmath> #include<cstdio> #include<cstring> #include<cassert> #include<algorithm> using namespace std;
namespace GEO{ typedef long long llong; const double EPS=1e-15; inline llong square(const int &key){return 1ll*key*key;} inline int sgn(const llong &key){ if(!key) return 0; return key<0? -1:1; } inline int sgn(const int &key){ if(!key) return 0; return key<0? -1:1; } inline int sgn(const double &key){ if(fabs(key)<EPS) return 0; return key<0? -1:1; } struct Vector{ int x,y; Vector(int _x=0,int _y=0):x(_x),y(_y){} friend double angle(const Vector &u,const Vector &v){ return acos(double((long double)dot(u,v)/(long double)u.len()/(long double)v.len())); } friend llong dot(const Vector &u,const Vector &v){return 1ll*u.x*v.x+1ll*u.y*v.y;} friend llong cross(const Vector &u,const Vector &v){return 1ll*u.x*v.y-1ll*u.y*v.x;} double len()const{return sqrt(square(x)+square(y));} }; struct Point{ int x,y; Point(int _x=0,int _y=0):x(_x),y(_y){} Vector operator -(const Point &v)const{return Vector(x-v.x,y-v.y);} Point operator +(const Vector &v)const{return Point(x+v.x,y+v.y);} friend llong distPoint2(const Point &u,const Point &v){return square(u.x-v.x)+square(u.y-v.y);} }; struct Line{ Point p;Vector d; Line(){} Line(Point _p,Vector _d):p(_p),d(_d){} Line(Point s,Point t):p(s),d(t-s){} }; int fixSide(const Point &s,const Point &t,const Point now){ return sgn(cross(t-s,now-s)); } bool cmpPointToX(const Point &u,const Point &v){ return sgn(u.x-v.x)? sgn(u.x-v.x)<0:sgn(u.y-v.y)<0; } bool cmpPointToY(const Point &u,const Point &v){ return sgn(u.y-v.y)? sgn(u.y-v.y)<0:sgn(u.x-v.x)<0; } void buildConvex(Point *org,int n,Point *res,int &nres){ nres=0; sort(org,org+n,cmpPointToX); for(int i=0;i<n;i++){ while(nres>1 && fixSide(res[nres-2],res[nres-1],org[i])<=0) nres--; res[nres++]=org[i]; } int tmp=nres; for(int i=n-2;~i;i--){ while(nres>tmp && fixSide(res[nres-2],res[nres-1],org[i])<=0) nres--; res[nres++]=org[i]; } nres--; } void modelizeConvex(Point *org,int n){ int it=0; for(int i=1;i<n;i++) if(cmpPointToY(org[i],org[it])) it=i; rotate(org,org+it,org+n); } void Minkowski(Point *pa,int na,Point *pb,int nb,Point *res,int &nres){ modelizeConvex(pa,na),modelizeConvex(pb,nb); pa[na]=pa[0],pb[nb]=pb[0]; int ma=0,mb=0;nres=0; Point now=Point(pa[0].x+pb[0].x,pa[0].y+pb[0].y); res[nres++]=now; while(ma<na && mb<nb){ int re=sgn(cross(pa[ma+1]-pa[ma],pb[mb+1]-pb[mb])); if(!re) now=now+(pa[ma+1]-pa[ma])+(pb[mb+1]-pb[mb]),ma++,mb++; else if(re>0) now=now+(pa[ma+1]-pa[ma]),ma++; else now=now+(pb[mb+1]-pb[mb]),mb++; res[nres++]=now; } while(ma<na){ now=now+(pa[ma+1]-pa[ma]),ma++; res[nres++]=now; } while(mb<nb){ now=now+(pb[mb+1]-pb[mb]),mb++; res[nres++]=now; } nres--; } } using namespace GEO;
const int N=1e5+10;
int nA,nB,nply,cas,mA,mB; Point ply[N<<1],covA[N<<1],covB[N];
bool ifFarthar(const Point &u,const Point &v){ return distPoint2(ply[0],u)<distPoint2(ply[0],v); } bool ifOutside(const Point &it){ if(fixSide(ply[0],ply[1],it)<0 || fixSide(ply[0],ply[nply-1],it)>0) return true; if(fixSide(ply[0],ply[1],it)==0) return ifFarthar(ply[1],it); if(fixSide(ply[0],ply[nply-1],it)==0) return ifFarthar(ply[nply-1],it); Vector vit=it-ply[0]; int lef=1,rig=nply-1; while(lef+1<rig){ int mid=(lef+rig)>>1,re=sgn(cross(ply[mid]-ply[0],vit)); if(!re) return ifFarthar(ply[mid],it); if(re<0) rig=mid; else lef=mid; } int re=sgn(cross(ply[lef]-it,ply[rig]-it)); return re<0; } int main(){ scanf("%d%d%d",&nA,&nB,&cas); for(int i=0;i<nA;i++) scanf("%d%d",&ply[i].x,&ply[i].y); buildConvex(ply,nA,covA,mA); for(int i=0;i<nB;i++){ scanf("%d%d",&ply[i].x,&ply[i].y); ply[i].x*=-1,ply[i].y*=-1; } buildConvex(ply,nB,covB,mB); Minkowski(covA,mA,covB,mB,ply,nply); for(int t=1;t<=cas;t++){ Point mov;scanf("%d%d",&mov.x,&mov.y); printf("%d\n",!ifOutside(mov)); } return 0; }
|