POJ 3130 半平面交+模版改进

View Code
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <vector>
  8 #include <deque>
  9 
 10 using namespace std;
 11 
 12 #define print(x) cout<<x<<endl
 13 #define input(x) cin>>x
 14 
 15 const double inf=1e100;
 16 const double eps=1e-10;
 17 
 18 inline int zero(double x)
 19 {
 20     if(x<-eps) return -1;
 21     else if(fabs(x)<eps) return 0;
 22     else return 1;
 23 }
 24 
 25 struct point
 26 {
 27     double x,y;
 28     point(){}
 29     point(double i_x,double i_y)
 30     {
 31         x=i_x;y=i_y;
 32     }
 33     friend bool operator == (const point& pa,const point& pb)
 34     {
 35         return (!zero(pa.x-pb.x)) && (!zero(pa.y-pb.y));
 36     }
 37 };
 38 
 39 struct segment
 40 {
 41     point p1,p2;
 42     segment(){}
 43     segment(const point& i_p1,const point& i_p2)
 44     {
 45         p1=i_p1;p2=i_p2;
 46     }
 47 };
 48 
 49 struct line
 50 {
 51     double a,b,c;
 52     line(){}
 53     line(double i_a,double i_b,double i_c)
 54     {
 55         a=i_a;b=i_b;c=i_c;
 56     }
 57 };
 58 
 59 inline double xmult(point sp,point ep,point op)
 60 {
 61     return ((sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x));
 62 }
 63 
 64 line makeline(point p1,point p2)
 65 {
 66     line res;
 67     int sig=1;
 68     res.a=p2.y-p1.y;
 69     if(zero(res.a)<0)
 70     {
 71         sig=-1;
 72         res.a=sig*res.a;
 73     }
 74     res.b=sig*(p1.x-p2.x);
 75     res.c=sig*(p1.y*p2.x-p2.y*p1.x);
 76     return res;
 77 }
 78 
 79 line makeline(segment s)
 80 {
 81     return makeline(s.p1,s.p2);
 82 }
 83 
 84 bool lineIntersect(line l1,line l2,point &p)
 85 {
 86     double d=l1.a*l2.b-l2.a*l1.b;
 87     if(fabs(d)<eps) return false;
 88     else
 89     {
 90         p.x = (l2.c*l1.b-l1.c*l2.b)/d;
 91         p.y = (l2.a*l1.c-l1.a*l2.c)/d;
 92         return true;
 93     }
 94 }
 95 
 96 bool segIntersect(segment s1,segment s2,point &p)
 97 {
 98     if( (max(s1.p1.x,s1.p2.x)>=min(s2.p1.x,s2.p2.x)) &&
 99         (max(s1.p1.y,s1.p2.y)>=min(s2.p1.y,s2.p2.y)) &&
100         (max(s2.p1.x,s2.p2.x)>=min(s1.p1.x,s1.p2.x)) &&
101         (max(s2.p1.y,s2.p2.y)>=min(s1.p1.y,s1.p2.y)) &&
102         !zero(xmult(s1.p1,s2.p1,s2.p2) * xmult(s1.p2,s2.p1,s2.p2)) &&
103         !zero(xmult(s2.p1,s1.p1,s1.p2) * xmult(s2.p2,s1.p1,s1.p2)))
104     {
105         lineIntersect(makeline(s1),makeline(s2),p);
106         return true;
107     }
108     else return false;
109 }
110 
111 struct polygen
112 {
113     deque<point> pvec;
114     
115     //如果是顺时针序,则clockwise=true
116     //否则是将其设为false
117     void push_point(const point& i_p,bool clockwise=true)
118     {
119         if(clockwise) pvec.push_back(i_p);
120         else pvec.push_front(i_p);
121     }
122     
123     void KernelCut(segment s)
124     {
125         deque<point> core;
126         int sz=(int)pvec.size();
127         for(int i=0;i<sz;i++)
128         {
129             if(zero(xmult(pvec[i],s.p2,s.p1))>=0)
130             {
131                 core.push_back(pvec[i]);
132             }
133             else
134             {
135                 point cp;
136                 if(zero(xmult(pvec[i],s.p2,s.p1) * xmult(pvec[(i-1+sz)%sz],s.p2,s.p1))<0)
137                 {
138                     line l1=makeline(s);
139                     line l2=makeline(pvec[i],pvec[(i-1+sz)%sz]);
140                     lineIntersect(l1,l2,cp);
141                     core.push_back(cp);
142                 }
143                 
144                 if(zero(xmult(pvec[i],s.p2,s.p1) * xmult(pvec[(i+1)%sz],s.p2,s.p1))<0)
145                 {
146                     line l1=makeline(s);
147                     line l2=makeline(pvec[i],pvec[(i+1)%sz]);
148                     lineIntersect(l1,l2,cp);
149                     core.push_back(cp);
150                 }
151             }
152         }
153         pvec=core;
154     }
155 
156     void getKernel()
157     {
158         deque<point> backup;
159         backup=pvec;
160         int sz=backup.size();
161         for(int i=0;i<sz;i++)
162         {
163             KernelCut(segment(backup[i],backup[(i+1)%sz]));
164         }
165     }
166 };
167 
168 int main()
169 {
170     int n;
171     double a,b;
172     while(input(n) && n)
173     {
174         polygen poly;
175         for(int i=0;i<n;i++)
176         {
177             input(a>>b);
178             poly.push_point(point(a,b),false);
179         }
180         poly.getKernel();
181         if(poly.pvec.size()>0) print(1);
182         else print(0);
183     }
184     return 0;
185 }

posted on 2012-06-27 14:04  Wizmann  阅读(215)  评论(0)    收藏  举报

导航