[HDU1756]Cupid's Arrow
题目大意:
给你一个简单多边形和若干个点,问每个点在多边形内还是外。
思路:
一开始没看清楚题,写了一个叉积法,事实上叉积法只能用来处理凸多边形与点的关系。
考虑一个射线法。
从这个点水平往左作一条射线,如果与多边形相交次数为偶数,则在多边形外,否则在多边形内。
考虑一些特殊情况:
1.射线与多边形某条边重合,不算。
2.射线经过某个顶点,只能够算一次。
对于第一种情况,我们只需要判一下是否平行即可,对于第二种情况,我们对于多边形上的边区分一下上顶点和下顶点即可,上顶点算,下顶点不算。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int N=100; 12 struct Point { 13 double x,y; 14 }; 15 Point p[N]; 16 int main() { 17 int n; 18 while(~scanf("%d",&n)) { 19 for(register int i=0;i<n;i++) { 20 p[i]=(Point){getint(),getint()}; 21 } 22 for(register int m=getint();m;m--) { 23 const Point q=(Point){getint(),getint()}; 24 int cnt=0; 25 if(p[0].y==p[n-1].y) { 26 } else if(p[0].x==p[n-1].x) { 27 if(p[0].x<q.x&&std::min(p[0].y,p[n-1].y)<q.y&&q.y<=std::max(p[0].y,p[n-1].y)) { 28 cnt++; 29 } 30 } else if((q.y-p[n-1].y)/((p[0].y-p[n-1].y)/(p[0].x-p[n-1].x))+p[n-1].x<=q.x) { 31 if(std::min(p[0].y,p[n-1].y)<q.y&&q.y<=std::max(p[0].y,p[n-1].y)) { 32 cnt++; 33 } 34 } 35 for(register int i=1;i<n;i++) { 36 if(p[i].y==p[i-1].y) { 37 } else if(p[i].x==p[i-1].x) { 38 if(p[i].x<q.x&&std::min(p[i].y,p[i-1].y)<q.y&&q.y<=std::max(p[i].y,p[i-1].y)) { 39 cnt++; 40 } 41 } else if((q.y-p[i-1].y)/((p[i].y-p[i-1].y)/(p[i].x-p[i-1].x))+p[i-1].x<=q.x) { 42 if(std::min(p[i].y,p[i-1].y)<q.y&&q.y<=std::max(p[i].y,p[i-1].y)) { 43 cnt++; 44 } 45 } 46 } 47 puts((cnt&1)?"Yes":"No"); 48 } 49 } 50 return 0; 51 }