ZOJ 1010 判断简单多边形+求面积
题解:
好题,计算几何的好题就是数据好!
然我找到了不规范相交的模板~
简单多边形用不规范相交搞,然后面积随便选用每条边(边是逆时针方向的)的端点和原点做叉积,就是面积(取绝对值)~
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 8 #define N 22222 9 #define EPS 1e-7 10 11 using namespace std; 12 13 struct PO 14 { 15 double x,y; 16 }p[N],o; 17 18 struct LI 19 { 20 PO a,b; 21 }li[N]; 22 23 int n,gs; 24 25 inline void read() 26 { 27 o.x=o.y=0.0; 28 for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); 29 for(int i=1;i<n;i++) li[i].a=p[i],li[i].b=p[i+1]; 30 li[n].a=p[n]; li[n].b=p[1]; 31 for(int i=1;i<=n;i++) li[i+n]=li[i]; 32 } 33 34 inline int doublecmp(double x) 35 { 36 if(x>EPS) return 1; 37 else if(x<-EPS) return -1; 38 return 0; 39 } 40 41 inline double cross(PO &a,PO &b,PO &c) 42 { 43 return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x); 44 } 45 46 inline double dot(PO &a,PO &b,PO &c) 47 { 48 return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y); 49 } 50 51 inline bool segcross(LI &a,LI &b)//不规范相交 52 { 53 int p1,p2,d1,d2; 54 //b跨立a 55 p1=doublecmp(cross(a.a,a.b,b.a)); 56 p2=doublecmp(cross(a.a,a.b,b.b)); 57 //a跨立b 58 d1=doublecmp(cross(b.a,b.b,a.a)); 59 d2=doublecmp(cross(b.a,b.b,a.b)); 60 if(p1*p2<0&&d1*d2<0) return true; 61 else if(p1*p2==0&&d1*d2==0&&(doublecmp(dot(b.a,a.a,a.b))<=0||doublecmp(dot(b.b,a.a,a.b))<=0)) return true;//a,b共线且有重合 62 else if(p1*p2==0&&(doublecmp(dot(b.a,a.a,a.b))<=0||doublecmp(dot(b.b,a.a,a.b))<=0)) return true;//b的端点在a上 63 else if(d1*d2==0&&(doublecmp(dot(a.a,b.a,b.b))<=0||doublecmp(dot(a.b,b.a,b.b))<=0)) return true;//a的端点在b上 64 else return false; 65 } 66 67 inline bool judge() 68 { 69 if(n<=2) return false; 70 for(int i=1;i<=n;i++) 71 for(int j=i+2;j<=i+n-2;j++) 72 if(segcross(li[i],li[j])) return false; 73 return true; 74 } 75 76 inline double getarea() 77 { 78 p[n+1]=p[1]; 79 double ans=0.0; 80 for(int i=1;i<=n;i++) ans+=cross(o,p[i],p[i+1]); 81 return ans; 82 } 83 84 inline void go() 85 { 86 if(gs!=0) printf("\n"); 87 printf("Figure %d: ",++gs); 88 if(judge()) printf("%.2lf\n",fabs(getarea())*0.5); 89 else printf("Impossible\n"); 90 } 91 92 int main() 93 { 94 while(scanf("%d",&n),n) read(),go(); 95 return 0; 96 }
这题数据真心强~
没有人能阻止我前进的步伐,除了我自己!