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 }

 

这题数据真心强~

 

你可能感兴趣的:(ZOJ)