【边界 几何】 Balloons in a Box

传送门

题意

在一个给定一对对角点的长方体内,给定\(n\)个点,依次放入气球,气球会膨胀直到碰到长方体的边界或者其他的气球
求所有点都放上气球的后能取得的最大体积,输出长方体体积与它的差

数据范围

\(1\leq n \leq 6\)

题解

  • 两个对角线上的点,每一个可以确定三个面,就构成了长方体的边界
  • 数据范围很小,爆搜所有可能的排列即可
  • 每一次都要判断当前点是否在长方体内部
  • 判断当前点是否位于已经充气的气球的内部
  • 合法的半径必定不碰边界,不接触其他气球,故二者去最小值即半径

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define close ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define db double
const db pi=acos(-1.0);
struct point
{
    db x,y,z;
    db d_to_wall;
};

point p[10];
point bor[10];
int n;
bool st[10];
db mx=-1e16;
int path[10];
db r[10];




bool inbox(point a)
{
    db xmx=max(bor[1].x,bor[2].x);
    db xmi=min(bor[1].x,bor[2].x);
    db ymx=max(bor[1].y,bor[2].y);
    db ymi=min(bor[1].y,bor[2].y);
    db zmx=max(bor[1].z,bor[2].z);
    db zmi=min(bor[1].z,bor[2].z);

    if(a.x > xmi && a.x < xmx && a.y > ymi &&a.y < ymx &&a.z > zmi &&a.z < zmx)
        return 1;
    else return 0;
}
db dist(point a,point b)
{   
    db x=a.x-b.x;
    db y=a.y-b.y;
    db z=a.z-b.z;
    return sqrt(x*x + y*y + z*z);
}
db mindist(point a)
{
    db minx=min(fabs(a.x - bor[1].x),fabs(a.x - bor[2].x));
    db miny=min(fabs(a.y - bor[1].y),fabs(a.y - bor[2].y));
    db minz=min(fabs(a.z - bor[1].z),fabs(a.z - bor[2].z));
    return min(minx,min(miny,minz));
}
db calc()
{
    db res=0;
    rep(i,1,n+1)
    {
        db mi=1e10;
        if(!inbox(p[path[i]])) 
        {
            r[i]=0;
            continue;
        }
        bool ok=1;
        rep(j,1,i)
        {
            db d=dist(p[path[j]],p[path[i]]);
            if(d<r[j])
            {
                ok=0;
                break;
            }
            mi = min(mi,d-r[j]);
        }
        
        if(!ok) 
        {
            r[i]=0;
            continue;
        }
        r[i] = min(mi,p[path[i]].d_to_wall);
        res = res+pi*r[i]*r[i]*r[i]*4.0/3.0;
    }
    return res;
}
void dfs(int u)
{
    if(u==n+1)
    {
        memset(r,0,sizeof r);
        mx = max(calc(),mx);
        return;
    }
    rep(i,1,n+1)
    {
        if(!st[i])
        {
            path[u]=i;
            st[i]=1;
            dfs(u+1);
            st[i]=0;
        }
    }
}
int main(){
    close
    int T = 0;
    while(cin>>n,n)
    {
        mx=-1e14;
        memset(st,0,sizeof st);
        cin>>bor[1].x>>bor[1].y>>bor[1].z;
        cin>>bor[2].x>>bor[2].y>>bor[2].z;
        db v =fabs(bor[1].x-bor[2].x) * fabs(bor[1].y-bor[2].y) * fabs(bor[1].z-bor[2].z);
        rep(i,1,n+1)
            cin>>p[i].x>>p[i].y>>p[i].z;
        rep(i,1,n+1)
            p[i].d_to_wall=mindist(p[i]);
        dfs(1);
        db ans=v-mx;
        cout << "Box " << ++T << ": " << (int) (ans + 0.5) << endl << endl;
    }   
}
posted @ 2020-08-11 01:31  Hyx'  阅读(120)  评论(0)    收藏  举报