题意:
判断点在多边形内
题解:
随机一个区域外的点,与所有线段求交,如果点数为奇数,则在多边形内,反之,在多边形外
需要注意:
1、与多边形的顶点相交时,重新随机一个点
2、点若在多边形上的话,直接返回奇数(我就在这里tle了。。一直随机,不停了。。。)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <ctime> 8 9 #define N 222 10 #define EPS 1e-7 11 12 using namespace std; 13 14 struct PO 15 { 16 double x,y; 17 }p[N]; 18 19 struct LI 20 { 21 PO a,b; 22 }li[N]; 23 24 int n,m; 25 26 inline int doublecmp(double x) 27 { 28 if(x>EPS) return 1; 29 else if(x<-EPS) return -1; 30 return 0; 31 } 32 33 inline double cross(PO &a,PO &b,PO &c) 34 { 35 return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x); 36 } 37 38 inline void read() 39 { 40 for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); 41 for(int i=1;i<n;i++) li[i].a=p[i],li[i].b=p[i+1]; 42 li[n].a=p[n]; li[n].b=p[1]; 43 scanf("%d",&m); 44 } 45 46 inline int segcross(LI &a,LI &b) 47 { 48 int p1,p2,d1,d2; 49 //b跨立a 50 p1=doublecmp(cross(a.a,a.b,b.a)); 51 p2=doublecmp(cross(a.a,a.b,b.b)); 52 //a跨立b 53 d1=doublecmp(cross(b.a,b.b,a.a)); 54 d2=doublecmp(cross(b.a,b.b,a.b)); 55 if(p1==0||p2==0) return -1;//多边形的边的端点在射线上 56 else if(p1*p2<=0&&d1*d2<=0) return 1; 57 else return 0; 58 } 59 60 inline bool inside(PO &a,PO &b,PO &c)//点在直线上 61 { 62 if(!doublecmp(cross(a,b,c))&&doublecmp((b.x-a.x)*(c.x-a.x))<=0&&doublecmp((b.y-a.y)*(c.y-a.y))<=0) return true; 63 return false; 64 } 65 66 inline int getnum() 67 { 68 int ans,i=0,tmp; 69 while(i<=n) 70 { 71 li[i].b.x=rand()+1000.0; 72 li[i].b.y=rand()+1000.0; 73 ans=0; 74 for(i=1;i<=n;i++) 75 { 76 if(inside(li[0].a,li[i].a,li[i].b)) return 1;//点在多边形上 77 tmp=segcross(li[0],li[i]); 78 if(tmp==-1) break; 79 else if(tmp==1) ans++; 80 } 81 } 82 return ans; 83 } 84 85 inline void go() 86 { 87 int ans; 88 while(m--) 89 { 90 scanf("%lf%lf",&li[0].a.x,&li[0].a.y); 91 if(getnum()&1) puts("Yes"); 92 else puts("No"); 93 } 94 } 95 96 int main() 97 { 98 while(scanf("%d",&n)!=EOF) read(),go(); 99 return 0; 100 }