您的位置:首页 > 其它

ZOJ 1010 判断简单多边形+求面积

2013-02-24 00:57 507 查看
题解:

好题,计算几何的好题就是数据好!

然我找到了不规范相交的模板~

简单多边形用不规范相交搞,然后面积随便选用每条边(边是逆时针方向的)的端点和原点做叉积,就是面积(取绝对值)~

View Code

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#define N 22222
#define EPS 1e-7

using namespace std;

struct PO
{
double x,y;
}p
,o;

struct LI
{
PO a,b;
}li
;

int n,gs;

inline void read()
{
o.x=o.y=0.0;
for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=1;i<n;i++) li[i].a=p[i],li[i].b=p[i+1];
li
.a=p
; li
.b=p[1];
for(int i=1;i<=n;i++) li[i+n]=li[i];
}

inline int doublecmp(double x)
{
if(x>EPS) return 1;
else if(x<-EPS) return -1;
return 0;
}

inline double cross(PO &a,PO &b,PO &c)
{
return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
}

inline double dot(PO &a,PO &b,PO &c)
{
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}

inline bool segcross(LI &a,LI &b)//不规范相交
{
int p1,p2,d1,d2;
//b跨立a
p1=doublecmp(cross(a.a,a.b,b.a));
p2=doublecmp(cross(a.a,a.b,b.b));
//a跨立b
d1=doublecmp(cross(b.a,b.b,a.a));
d2=doublecmp(cross(b.a,b.b,a.b));
if(p1*p2<0&&d1*d2<0) return true;
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共线且有重合
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上
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上
else return false;
}

inline bool judge()
{
if(n<=2) return false;
for(int i=1;i<=n;i++)
for(int j=i+2;j<=i+n-2;j++)
if(segcross(li[i],li[j])) return false;
return true;
}

inline double getarea()
{
p[n+1]=p[1];
double ans=0.0;
for(int i=1;i<=n;i++) ans+=cross(o,p[i],p[i+1]);
return ans;
}

inline void go()
{
if(gs!=0) printf("\n");
printf("Figure %d: ",++gs);
if(judge()) printf("%.2lf\n",fabs(getarea())*0.5);
else printf("Impossible\n");
}

int main()
{
while(scanf("%d",&n),n) read(),go();
return 0;
}


这题数据真心强~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: