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 }

这题数据真心强~

原文地址:https://www.cnblogs.com/proverbs/p/2923930.html