【边界 几何】 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;
}
}

浙公网安备 33010602011771号