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 }

你可能感兴趣的:(poj)