题解:
射线法判定点是否在多边形内部;
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 const double esp=1e-8; 6 const int maxn=100+50; 7 8 int n,m; 9 struct Point 10 { 11 double x,y; 12 }p[maxn]; 13 14 double K(Point p1,Point p2) 15 { 16 return (p2.y-p1.y)/(p2.x-p1.x); 17 } 18 bool onEdge(Point q,Point p1,Point p2) 19 { 20 if(p1.x == p2.x)//斜率不存在的情况,HDU的数据里没有卡这种情况 21 return q.y >= min(p1.y,p2.y) && q.y <= max(p1.y,p2.y) && q.x == p1.x ? true:false; 22 23 if(q.x >= min(p1.x,p2.x) && q.x <= max(p1.x,p2.x) && q.y >= min(p1.y,p2.y) && q.y <= max(p1.y,p2.y)) 24 return fabs(K(p1,q)-K(p1,p2)) < esp ? true:false; 25 return false; 26 } 27 bool inPolygon(Point q) 28 { 29 int ans=0; 30 Point p1,p2; 31 p1=p[0]; 32 for(int i=1;i <= n;++i) 33 { 34 p2=p[i%n]; 35 if(onEdge(q,p1,p2)) 36 return true; 37 if(p1.y == p2.y)//判断p1p2是否为水平边,水平边不作考虑 38 { 39 p1=p2;//起初,这儿我并没有加这句话,改了好半天才看到 40 continue; 41 } 42 /** 43 注意:此处q.y是严格>min(); 44 此处是用来处理射线与顶点相交的情况的 45 当相交的顶点为凸顶点时,两条边都加上; 46 当相交的顶点是凹顶点时,只加右边那条边; 47 */ 48 if(q.y > min(p1.y,p2.y) && q.y <= max(p1.y,p2.y) && q.x <= max(p1.x,p2.x)) 49 { 50 //当p1p2为竖线时,由条件q.x <= max(p1.x,p2.x)可得由p向右发出的射线与p1p2有交点 51 if(p1.x == p2.x) 52 ans++; 53 else 54 { 55 //x : 经过q点且平行于x轴的直线与p1p2交点的横坐标 56 double x=p1.x+(q.y-p1.y)/K(p1,p2); 57 if(q.x <= x)//如果q.x <= x,说明q向右发出的射线与p1p2有交点 58 ans++; 59 } 60 } 61 p1=p2; 62 } 63 return ans&1; 64 } 65 int main() 66 { 67 // freopen("C:\Users\hyacinthLJP\Desktop\in&&out\HDU\1756.in","r",stdin); 68 while(~scanf("%d",&n)) 69 { 70 for(int i=0;i < n;++i) 71 scanf("%lf%lf",&p[i].x,&p[i].y); 72 73 scanf("%d",&m); 74 for(int i=1;i <= m;++i) 75 { 76 Point q; 77 scanf("%lf%lf",&q.x,&q.y); 78 if(inPolygon(q)) 79 printf("Yes "); 80 else 81 printf("No "); 82 } 83 } 84 return 0; 85 }