您的位置:首页 > 编程语言 > Go语言

【2011 Greater New York Regional 】Problem I :The Golden Ceiling

2013-10-02 10:49 381 查看
一道比较简单但是繁琐的三维计算几何,找错误找的我好心酸,没想到就把一个变量给写错了 = =;

题目的意思是求平面切长方体的截面面积+正方体顶部所遮盖的面积;

找出所有的切点,然后二维凸包一下直接算面积即可!

发个代码纪念一下!

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define eps 1e-8
using namespace std;

inline int sig(double x){return (x>eps)-(x<-eps);}
double w,l,hh,aa,bb,cc,dd;
int num1,num2;
struct point
{
double x,y,z;
point(double x=0,double y=0,double z=0):x(x),y(y),z(z) { }
bool operator < (const point &t)const
{
if(sig(x-t.x)==0)
{
return y<t.y;
}
else return x<t.x;
}
point operator+(const point&b)const{return point(x+b.x,y+b.y,z+b.z);}
point operator-(const point&b)const{return point(x-b.x,y-b.y,z-b.z);}
point operator*(double p){return point(x*p,y*p,z*p);}
point operator/(double p){return point(x/p,y/p,z/p);}
} ve[12],tu[6],vv[12],tt[6];

void intersection(point a,point b)
{
double t=(aa*a.x+bb*a.y+cc*a.z+dd)/(aa*(a.x-b.x)+bb*(a.y-b.y)+cc*(a.z-b.z));
if(t>=-eps&&t<=1.00000+eps)
{
point v=a+(b-a)*t;
ve[num1++]=v;
if(sig(v.z-hh)==0)
tu[num2++]=v;
}
}
double lenth(point a){return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);}
point cross(point a,point b){return point(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);}
double area(point a,point b,point c){return lenth(cross(b-a,c-a))/2.0;}
double cross2(point a,point b){return a.x*b.y-a.y*b.x;}
bool check(point a)
{
if(sig(aa*a.x+bb*a.y+cc*a.z+dd)<0)
return 1;
return 0;
}

int convexhull(point *p,int n,point* ch)
{
sort(p,p+n);
int m=0;
for(int i=0;i<n;i++)
{
while(m>1&&cross2(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=eps)m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--)
{
while(m>k&&cross2(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=eps)m--;
ch[m++]=p[i];
}
if(n>1)m--;
return m;
}

int main()
{
int t,ca;
scanf("%d",&t);
while(t--)
{
memset(tu,0,sizeof tu);
memset(ve,0,sizeof ve);
memset(vv,0,sizeof vv);
memset(tt,0,sizeof tt);
scanf("%d",&ca);
printf("%d ",ca);
scanf("%lf%lf%lf%lf%lf%lf%lf",&l,&w,&hh,&aa,&bb,&cc,&dd);
num1=num2=0;
dd=-dd;
point a(0.0,0.0,0.0);
point b(l,0.0,0.0);
point c(l,w,0.0);
point d(0.0,w,0.0);
point e(0.0,0.0,hh);
point f(l,0.0,hh);
point g(l,w,hh);
point h(0.0,w,hh);
intersection(a,b);
intersection(b,c);
intersection(c,d);
intersection(d,a);
intersection(a,e);
intersection(b,f);
intersection(c,g);
intersection(d,h);
intersection(e,f);
intersection(f,g);
intersection(g,h);
intersection(h,e);
if(check(e)==1)tu[num2++]=e;
if(check(f)==1)tu[num2++]=f;
if(check(g)==1)tu[num2++]=g;
if(check(h)==1)tu[num2++]=h;
int x=convexhull(ve,num1,vv);
int y=convexhull(tu,num2,tt);
double ans=0;
for(int i=2;i<x;i++)
ans+=area(vv[0],vv[i-1],vv[i]);
for(int i=2;i<y;i++)
ans+=area(tt[0],tt[i-1],tt[i]);
printf("%.0lf\n",ceil(ans));
}
return 0;
}


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