三维凸包
模板题:洛谷p4724
#include<bits/stdc++.h> #define eps 1e-9; using namespace std; const int N=500010; int n; int vis[1010][1010]; struct Point{ double x,y,z; void shake(){ double Rand=(rand()/RAND_MAX-0.5)*eps; x+=Rand;y+=Rand;z+=Rand; } double len(){ return sqrt(x*x+y*y+z*z); } }point[N]; Point operator +(Point A,Point B){ return (Point){A.x+B.x,A.y+B.y,A.z+B.z}; } Point operator -(Point A,Point B){ return (Point){A.x-B.x,A.y-B.y,A.z-B.z}; } Point operator ^(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 operator *(Point A,Point B){ return A.x*B.x+A.y*B.y+A.z*B.z; } struct Plane{ int num[3]; Point legal(){ Point A=point[num[1]]-point[num[0]]; Point B=point[num[2]]-point[num[0]]; return A^B; } double S(){ return legal().len()/2.0; } }hull[N],stk[N]; int tp,cnt; double len(Point A,Plane B){ Point legal=B.legal(); return legal*(A-point[B.num[0]])/legal.len(); } bool see(Point A,Plane B){ return B.legal()*(A-point[B.num[0]])>0.0; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].z); point[i].shake(); } hull[++cnt]={1,2,3}; hull[++cnt]={3,2,1}; for(int i=4;i<=n;i++){ for(int j=1;j<=cnt;j++){ int v=see(point[i],hull[j]); if(!v)stk[++tp]=hull[j]; for(int now=0;now<3;now++){ int next=(now+1)%3; int from=hull[j].num[now]; int to=hull[j].num[next]; vis[from][to]=v; } } for(int j=1;j<=cnt;j++){ for(int now=0;now<3;now++){ int next=(now+1)%3; int from=hull[j].num[now]; int to=hull[j].num[next]; if(vis[from][to]&&!vis[to][from]){ stk[++tp]={from,to,i}; } } } for(int j=1;j<=tp;j++){ hull[j]=stk[j]; } cnt=tp,tp=0; } double ans=0; for(int i=1;i<=cnt;i++){ ans+=hull[i].S(); } printf("%.3f\n",ans); }