模板题
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #define lson l,mid,rt<<1 8 #define rson mid+1,r,rt<<1|1 9 #define root 1,n,1 10 #define mid ((l+r)>>1) 11 #define ll long long 12 #define cl(a) memset(a,0,sizeof(a)) 13 #define ts printf("***** "); 14 using namespace std; 15 const int MAXN=199999+9; 16 int sum[MAXN<<2],lsum[MAXN<<2],rsum[MAXN<<2]; 17 int n,m,tt; 18 const double eps = 1e-8; 19 const double PI = acos(-1.0); 20 int sgn(double x) 21 { 22 if(fabs(x) < eps)return 0; 23 if(x < 0)return -1; 24 else return 1; 25 } 26 struct Point 27 { 28 double x,y; 29 Point(){} 30 Point(double _x,double _y) 31 { 32 x = _x;y = _y; 33 } 34 Point operator -(const Point &b)const 35 { 36 return Point(x - b.x,y - b.y); 37 } 38 //叉积 39 double operator ^(const Point &b)const 40 { 41 return x*b.y - y*b.x; 42 } 43 //点积 44 double operator *(const Point &b)const 45 { 46 return x*b.x + y*b.y; 47 } 48 //绕原点旋转角度B(弧度值),后x,y的变化 49 void transXY(double B) 50 { 51 double tx = x,ty = y; 52 x = tx*cos(B) - ty*sin(B); 53 y = tx*sin(B) + ty*cos(B); 54 } 55 }; 56 //*判断点在线段上 57 struct Line 58 { 59 Point s,e; 60 Line(){} 61 Line(Point _s,Point _e) 62 { 63 s = _s;e = _e; 64 } 65 //两直线相交求交点 66 //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交 67 //只有第一个值为2时,交点才有意义 68 pair<int,Point> operator &(const Line &b)const 69 { 70 Point res = s; 71 if(sgn((s-e)^(b.s-b.e)) == 0) 72 { 73 if(sgn((s-b.e)^(b.s-b.e)) == 0) 74 return make_pair(0,res);//重合 75 else return make_pair(1,res);//平行 76 } 77 double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e)); 78 res.x += (e.x-s.x)*t; 79 res.y += (e.y-s.y)*t; 80 return make_pair(2,res); 81 } 82 }; 83 bool OnSeg(Point P,Line L) 84 { 85 return 86 sgn((L.s-P)^(L.e-P)) == 0 && 87 sgn((P.x - L.s.x) * (P.x - L.e.x)) <= 0 && 88 sgn((P.y - L.s.y) * (P.y - L.e.y)) <= 0; 89 } 90 bool inter(Line l1,Line l2) 91 { 92 return 93 max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) && 94 max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) && 95 max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) && 96 max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) && 97 sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 && 98 sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0; 99 } 100 //*判断点在任意多边形内 101 //射线法,poly[]的顶点数要大于等于3,点的编号0~n-1 102 //返回值 103 //-1:点在凸多边形外 104 //0:点在凸多边形边界上 105 //1:点在凸多边形内 106 int inPoly(Point p,Point poly[],int n) 107 { 108 int cnt; 109 Line ray,side; 110 cnt = 0; 111 ray.s = p; 112 ray.e.y = p.y; 113 ray.e.x = -100000000000.0;//-INF,注意取值防止越界 114 for(int i = 0;i < n;i++) 115 { 116 side.s = poly[i]; 117 side.e = poly[(i+1)%n]; 118 if(OnSeg(p,side))return 0; 119 //如果平行轴则不考虑 120 if(sgn(side.s.y - side.e.y) == 0) 121 continue; 122 if(OnSeg(side.s,ray)) 123 { 124 if(sgn(side.s.y - side.e.y) > 0)cnt++; 125 } 126 else if(OnSeg(side.e,ray)) 127 { 128 if(sgn(side.e.y - side.s.y) > 0)cnt++; 129 } 130 else if(inter(ray,side)) 131 cnt++; 132 } 133 if(cnt % 2 == 1)return 1; 134 else return -1; 135 } 136 137 Point a[MAXN],b; 138 int main() 139 { 140 int i,j,k; 141 #ifndef ONLINE_JUDGE 142 freopen("1.in","r",stdin); 143 #endif 144 while(scanf("%d",&n)!=EOF) 145 { 146 for(i=0;i<n;i++) 147 { 148 scanf("%lf%lf",&a[i].x,&a[i].y); 149 } 150 scanf("%d",&m); 151 for(i=0;i<m;i++) 152 { 153 scanf("%lf%lf",&b.x,&b.y); 154 if(inPoly(b,a,n)!=-1) 155 { 156 printf("Yes "); 157 } 158 else printf("No "); 159 } 160 } 161 }