【2011 Greater New York Regional 】Problem I :The Golden Ceiling
一道比较简单但是繁琐的三维计算几何,找错误找的我好心酸,没想到就把一个变量给写错了 = =;
题目的意思是求平面切长方体的截面面积+正方体顶部所遮盖的面积;
找出所有的切点,然后二维凸包一下直接算面积即可!
发个代码纪念一下!
代码:
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #define eps 1e-8 6 using namespace std; 7 8 inline int sig(double x){return (x>eps)-(x<-eps);} 9 double w,l,hh,aa,bb,cc,dd; 10 int num1,num2; 11 struct point 12 { 13 double x,y,z; 14 point(double x=0,double y=0,double z=0):x(x),y(y),z(z) { } 15 bool operator < (const point &t)const 16 { 17 if(sig(x-t.x)==0) 18 { 19 return y<t.y; 20 } 21 else return x<t.x; 22 } 23 point operator+(const point&b)const{return point(x+b.x,y+b.y,z+b.z);} 24 point operator-(const point&b)const{return point(x-b.x,y-b.y,z-b.z);} 25 point operator*(double p){return point(x*p,y*p,z*p);} 26 point operator/(double p){return point(x/p,y/p,z/p);} 27 } ve[12],tu[6],vv[12],tt[6]; 28 29 void intersection(point a,point b) 30 { 31 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)); 32 if(t>=-eps&&t<=1.00000+eps) 33 { 34 point v=a+(b-a)*t; 35 ve[num1++]=v; 36 if(sig(v.z-hh)==0) 37 tu[num2++]=v; 38 } 39 } 40 double lenth(point a){return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);} 41 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);} 42 double area(point a,point b,point c){return lenth(cross(b-a,c-a))/2.0;} 43 double cross2(point a,point b){return a.x*b.y-a.y*b.x;} 44 bool check(point a) 45 { 46 if(sig(aa*a.x+bb*a.y+cc*a.z+dd)<0) 47 return 1; 48 return 0; 49 } 50 51 int convexhull(point *p,int n,point* ch) 52 { 53 sort(p,p+n); 54 int m=0; 55 for(int i=0;i<n;i++) 56 { 57 while(m>1&&cross2(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=eps)m--; 58 ch[m++]=p[i]; 59 } 60 int k=m; 61 for(int i=n-2;i>=0;i--) 62 { 63 while(m>k&&cross2(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=eps)m--; 64 ch[m++]=p[i]; 65 } 66 if(n>1)m--; 67 return m; 68 } 69 70 int main() 71 { 72 int t,ca; 73 scanf("%d",&t); 74 while(t--) 75 { 76 memset(tu,0,sizeof tu); 77 memset(ve,0,sizeof ve); 78 memset(vv,0,sizeof vv); 79 memset(tt,0,sizeof tt); 80 scanf("%d",&ca); 81 printf("%d ",ca); 82 scanf("%lf%lf%lf%lf%lf%lf%lf",&l,&w,&hh,&aa,&bb,&cc,&dd); 83 num1=num2=0; 84 dd=-dd; 85 point a(0.0,0.0,0.0); 86 point b(l,0.0,0.0); 87 point c(l,w,0.0); 88 point d(0.0,w,0.0); 89 point e(0.0,0.0,hh); 90 point f(l,0.0,hh); 91 point g(l,w,hh); 92 point h(0.0,w,hh); 93 intersection(a,b); 94 intersection(b,c); 95 intersection(c,d); 96 intersection(d,a); 97 intersection(a,e); 98 intersection(b,f); 99 intersection(c,g); 100 intersection(d,h); 101 intersection(e,f); 102 intersection(f,g); 103 intersection(g,h); 104 intersection(h,e); 105 if(check(e)==1)tu[num2++]=e; 106 if(check(f)==1)tu[num2++]=f; 107 if(check(g)==1)tu[num2++]=g; 108 if(check(h)==1)tu[num2++]=h; 109 int x=convexhull(ve,num1,vv); 110 int y=convexhull(tu,num2,tt); 111 double ans=0; 112 for(int i=2;i<x;i++) 113 ans+=area(vv[0],vv[i-1],vv[i]); 114 for(int i=2;i<y;i++) 115 ans+=area(tt[0],tt[i-1],tt[i]); 116 printf("%.0lf\n",ceil(ans)); 117 } 118 return 0; 119 }