UVALive 4589 Asteroids (三维凸包&&重心)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define FRER() freopen("/Users/seven7777777/Desktop/Code/TESTXCODE/TESTXCODE/in.txt","r",stdin)
#define FREW() freopen("/Users/seven7777777/Desktop/Code/TESTXCODE/TESTXCODE/out.txt","w",stdout)
#define go int T;cin>>T;for(int kase=0;kase<T;kase++)
#define debug cout<<"****************"<<endl
#define lowbit(x) x&(-x)
#define eps 1e-6
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int maxn = 100 + 7;
struct Point3
{
    double x,y,z;
    Point3(double x = 0 , double y = 0,double z = 0):x(x),y(y),z(z){}
    void print(){
        printf("x:%lf y:%lf z:%lf",x,y,z);
    }
};
typedef Point3 Vector3;
Vector3 operator + (Vector3 A,Vector3 B){
    return Vector3(A.x+B.x,A.y+B.y,A.z+B.z);
}
Vector3 operator - (Vector3 A,Vector3 B){
    return Vector3(A.x-B.x,A.y-B.y,A.z-B.z);
}
Vector3 operator * (Vector3 A,double p){
    return Vector3(A.x*p,A.y*p,A.z*p);
}
Vector3 operator / (Vector3 A,double p){
    return Vector3(A.x/p,A.y/p,A.z/p);
}
double Dot(Vector3 A,Vector3 B){
    return A.x*B.x + A.y*B.y + A.z*B.z;
}
Vector3 Cross(Vector3 A,Vector3 B){
    return Vector3(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 Volume6(Point3 A,Point3 B,Point3 C,Point3 D){
    return Dot(D-A,Cross(B-A, C-A));
}
struct Face{
    int v[3];
    Face(int a=0,int b=0,int c=0){
        v[0] = a;
        v[1] = b;
        v[2] = c;
    }
    Vector3 Normal(Point3* p)const{
        return Cross(p[v[1]]-p[v[0]],p[v[2]]-p[v[0]]);
    }
    int cansee(Point3 *p,int i)const{
        return Dot(p[i]-p[v[0]],Normal(p)) > 0 ? 1 : 0;
    }
    void print(Point3 *p){
        cout<<"a ";p[v[0]].print();cout<<";";
        cout<<"b ";p[v[1]].print();cout<<";";
        cout<<"c ";p[v[2]].print();cout<<";";
        cout<<endl;
    }
};
double rand01(){return rand()/(double)RAND_MAX;}
double randeps(){return (rand01()-0.5)*eps;}
Point3 add_noise(Point3 p){
    return Point3(p.x+randeps(),p.y+randeps(),p.z+randeps());
}
vector<Face> CH3D(Point3* p,int n){
    int vis[maxn][maxn];
    vector<Face>cur;
    cur.push_back(Face(0,1,2));
    cur.push_back(Face(2,1,0));
    for(int i=3;i<n;i++){
        vector<Face>nxt;
        for(int j=0;j<cur.size();j++){
            Face& f = cur[j];
            int res = f.cansee(p,i);
            if(!res) nxt.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<cur.size();j++){
            for(int k=0;k<3;k++){
                int a = cur[j].v[k] , b = cur[j].v[(k+1)%3];
                if(vis[a][b]!=vis[b][a]&&vis[a][b]) nxt.push_back(Face(a,b,i));
            }
        }
        cur = nxt;
    }
    return cur;
}
double length(Vector3 A){
    return sqrt(Dot(A, A));
}
double DistanceToPlane(Point3 p,Point3 p0,Point3 n){
    return fabs(Dot(p-p0,n)/length(n));
}
double solve(Point3 *p,Point3* _p,int n,Point3 avg){
    //avg.print();
    vector<Face>f = CH3D(_p, n);
    Point3 base;
    int len = (int)f.size();
    double totv = 0;
    for(int i=0;i<len;i++){
        //f[i].print(p);
        double v = Volume6(p[f[i].v[0]], p[f[i].v[1]], p[f[i].v[2]], avg);
        base = base + (p[f[i].v[0]]+p[f[i].v[1]]+p[f[i].v[2]]+avg)/4*v;
        totv += v;
    }
    base = base / totv;
    //base.print();
    //debug;
    double ans = 9999999;
    for(int i=0;i<len;i++){
        Vector3 n = f[i].Normal(p);
        ans = min(ans,DistanceToPlane(base, p[f[i].v[0]], n));
        //cout<<ans<<endl;
    }
    //debug;
    return ans;
}
void read(Point3 *p,Point3 *_p,int n,Point3& avg){
    for(int i=0;i<n;i++){
        scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
        _p[i] = add_noise(p[i]);
        avg.x += p[i].x;avg.y += p[i].y;avg.z += p[i].z;
    }
    avg = avg/n;
}
Point3 plant1[maxn],plant2[maxn],_plant1[maxn],_plant2[maxn];
int n,m;
int main(){
    //FRER();
    //FREW();
     while(~scanf("%d",&n)){
         Point3 avg1,avg2;
         read(plant1,_plant1, n, avg1);
         scanf("%d",&m);
         read(plant2,_plant2, m, avg2);
         double ans1 = solve(plant1,_plant1,n,avg1);
         double ans2 = solve(plant2,_plant2,m,avg2);
         printf("%.5f\n",ans1+ans2);
     }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值