T^T ONLINE JUDGE 3313 盒子里的气球
盒子里的气球
TimeLimit:10000MS MemoryLimit:128MB
64-bit integer IO format:%lld
已解决 | 点击收藏
Problem Description
在一个长方体盒子里,有N(N≤6)个相异的点。在其中任何一个点上放一个很小的气球,那么这个气球会一直膨胀,直到接触到其它气球或者盒子的边界。必须等一个气球扩展完毕才能放置下一个气球。那么应该按照怎样的顺序在这N个点上放置气球,才能使放置完毕后所有气球占据的总体积最大呢?
注:球的体积公式 V = 4/3pi rrr,其中r为球的半径,pi=arccos(-1)
Input
第一行一个整数N
第二行为长方体盒子一个顶点及其对角顶点的坐标,x y z x’ y’ z’
接下去N行,每行三个整数x1 y1 z1,表示盒子内N个点的坐标
以上所有的整数都在[-1000, 1000]内
Output
长方体盒子剩余的最小空间(结果四舍五入输出)
SampleInput
2
0 0 0 10 10 10
3 3 3
7 7 7
SampleOutput
774
【思路】:
就是一个暴力的搜索,全排列再加上枚举每个点,因为题目给的N<=6的,所以直接暴力就对了,根据题意容易得知,每次要么碰到壁,要么与其他气球相接触,这样的话我们就可以再每次搜索的时候,往前面的搜索一次,可以得到min值。存到数组里,最后再遍历一次,可以得到结果,每次都更新答案就可以了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stdio.h>
using namespace std;
#define pi acos(-1)
typedef long long ll;
const ll inf = 0x7fffffffffffffff;
///在这里wa得太多了,本来是0xfffffff,但是会答案可能会爆掉inf
///后来我改成0x7fffffffffffffff,就ac了。。。。。
int n;
int xx,yy,zz;
const int MAXN = 10;
typedef struct MYint
{
int x;
int y;
int z;
} myint;
myint a,b;
myint math[MAXN];
int myabs(int sum)
{
if(sum<0)
return -sum;
else
return sum;
}
double sum=inf;///result
int vids[10];///标记数组
double R[10];///求r的值
int D[10];///标记上一级是啥
int flag=0;
void dfs(int t)///t 标记次数
{
if(t>=n)///得出答案
{
for(int i=0; i<n; i++)
{
s-=(4.0/3.0*pi*R[D[i]]*R[D[i]]*R[D[i]]);
}
sum=min(s,sum);///更新答案
return ;
}
else
{
for(int i=0; i<n; i++)
{
if(vids[i]==0)
{
vids[i]=1;
D[t]=i;
double r;
r=min(min(min(myabs(math[i].x-a.x),myabs(math[i].x-b.x)),
min(myabs(math[i].y-a.y),myabs(math[i].y-b.y))),
min(myabs(math[i].z-a.z),myabs(math[i].z-b.z)));///先查找到x,y,z面的最小值
for(int j=0; j<t; j++)
{
r=min(r,sqrt((math[D[j]].x-math[i].x)*(math[D[j]].x-math[i].x)+(math[D[j]].y-math[i].y)*(math[D[j]].y-math[i].y)+(math[D[j]].z-math[i].z)*(math[D[j]].z-math[i].z))
-R[D[j]]);
}///与前面存在的值比较进行更新
if(r<0.0)
{///如果点在球内,r<0.0,所以直接判断为0就对了
r=0.0;
}
R[i]=r;
dfs(t+1);
vids[i]=0;
}
}
}
}
int main()
{
scanf("%d",&n);
sum=inf;
memset(math,0,sizeof(math));
memset(vids,0,sizeof(vids));
scanf("%d%d%d%d%d%d",&a.x,&a.y,&a.z,&b.x,&b.y,&b.z);
xx=myabs(a.x-b.x);
yy=myabs(a.y-b.y);
zz=myabs(a.z-b.z);///计算xx,yy,zz
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&math[i].x,&math[i].y,&math[i].z);
}
dfs(0);
if(sum==inf)
printf("%.0f",double(xx*yy*zz));
else
printf("%.0f",sum);
return 0;
}