一眼扫过去,凸包?数据范围什么这么小?
10分钟码完了Andrew,发现答案不对……
卧槽怎么是三维的。。。。。。。
三维凸包不会啊TAT
对着白书抄了一遍增量法,水过去了(你这样真的好吗)
好吧回去再看一遍增量法,感觉很好玩的样子。
很想知道status里0MS的大爷是怎么做到的(随机增量?)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdlib>
using namespace std;
const double eps=1e-9;
const int N=100+5;
int dcmp(double x){
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
struct point{
double x,y,z;
}p[N],p1[N];
point operator - (point a,point b){
return (point){a.x-b.x,a.y-b.y,a.z-b.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};
}
point cross(point a,point b,point c){
return cross(b-a,c-a);
}
double dot(point a,point b){
return a.x*b.x+a.y*b.y+a.z*b.z;
}
double sqr(double x){return x*x;}
double length(point p){
return sqrt(sqr(p.x)+sqr(p.y)+sqr(p.z));
}
struct face{
int v[3];
point normal(point *p)const{
return cross(p[v[0]],p[v[1]],p[v[2]]);
}
int cansee(point *p,int i)const{
return dot(p[i]-p[v[0]],normal(p))>0;
}
};
double rand01(){
return rand()/(double)RAND_MAX;
}
double randeps(){
return (rand01()-0.5)*eps;
}
point add_noise(point p){
return (point){p.x+randeps(),p.y+randeps(),p.z+randeps()};
}
struct convexhull{
vector<face>ch;
bool vis[N][N];
void increment(point *p,int n){
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)p[i]=add_noise(p[i]);
ch.clear();
ch.push_back((face){{0,1,2}});
ch.push_back((face){{2,1,0}});
for(int i=3;i<n;i++){
vector<face>tmp;tmp.clear();
for(int j=0;j<ch.size();j++){
face f=ch[j];
int res=f.cansee(p,i);
if(!res)tmp.push_back(f);
for(int k=0;k<3;k++)vis[f.v[k]][f.v[(k+1)%3]]=res;
}
for(int j=0;j<ch.size();j++)
for(int k=0;k<3;k++){
int a=ch[j].v[k],b=ch[j].v[(k+1)%3];
if(vis[a][b]!=vis[b][a]&&vis[a][b])
tmp.push_back((face){a,b,i});
}
ch=tmp;
}
}
double area(point a,point b,point c){
return 0.5*length(cross(a,b,c));
}
double area(face f,point *p){
return area(p[f.v[0]],p[f.v[1]],p[f.v[2]]);
}
double area(point *p){
double ans=0;
for(int i=0;i<ch.size();i++)
ans+=area(ch[i],p);
return ans;
}
}sol;
int main(){
//freopen("a.in","r",stdin);
int n;scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
for(int i=0;i<n;i++)p1[i]=p[i];
sol.increment(p1,n);
printf("%.6lf\n",sol.area(p));
return 0;
}