标签:
对于所有数据,坐标范围在[0,100]*[0,100]*[0,100]。
直接水过,不过网上的三维凸包的标程一个比一个不靠谱,由一组数据拍出来,加上我的程序,三个程序三个答案。整个人都不好了。
枚举一个面,使得剩下两个点与这条面组成四面体的有向体积符号不同,则两点在面的两侧,计算即可。
四面体的计算公式是三个向量组成的矩阵行列式的1/6.
这是居然我的第一个三维算几题。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> using namespace std; #define MAXN 10 typedef double real; struct point { real x,y,z; point(real x,real y,real z):x(x),y(y),z(z){} point(){} void read() { scanf("%lf %lf %lf",&x,&y,&z); } }pl[MAXN];; real area(point p1,point p2,point p3) { return (p1.x*p2.y*p3.z + p1.z*p2.x*p3.y + p1.y*p2.z*p3.x -p1.x*p2.z*p3.y - p1.z*p2.y*p3.x - p1.y*p2.x*p3.z)/6; } point operator -(point p1,point p2) { return point(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z); } typedef point line; bool vis[MAXN]; int main() { freopen("input.txt","r",stdin); for (int i=0;i<5;i++) { pl[i].read(); } // printf("%.2lf\n",area(pl[1]-pl[0],pl[2]-pl[0],pl[3]-pl[0])); real ans=0; real s1,s2,s3; for (int a=0;a<5;a++) { vis[a]=true; for (int b=0;b<5;b++) { if (vis[b])continue; vis[b]=true; for (int c=0;c<5;c++) { if (vis[c])continue; vis[c]=true; for (int d=0;d<5;d++) { if (vis[d])continue; vis[d]=true; for (int e=0;e<5;e++) { if (vis[e])continue; vis[e]=true; s3=abs(s1=area(pl[c]-pl[a],pl[b]-pl[a],pl[d]-pl[a]))+abs(s2=area(pl[c]-pl[a],pl[b]-pl[a],pl[e]-pl[a])); if (s1*s2>0) { vis[e]=false;continue; } if (s1==0 && s2==0) { vis[e]=false;continue; } ans=max(ans,s3); vis[e]=false; } vis[d]=false; } vis[c]=false; } vis[b]=false; } vis[a]=false; } printf("%.2lf\n",ans); }
标签:
原文地址:http://www.cnblogs.com/mhy12345/p/4423697.html