HDU 1756 点在多边形内

题意:

判断点在多边形内

 

题解:

随机一个区域外的点,与所有线段求交,如果点数为奇数,则在多边形内,反之,在多边形外

需要注意:

1、与多边形的顶点相交时,重新随机一个点

2、点若在多边形上的话,直接返回奇数(我就在这里tle了。。一直随机,不停了。。。)

 

View Code
  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 }

 

 

posted @ 2013-02-23 21:35  proverbs  阅读(239)  评论(0编辑  收藏  举报