//用枚举的方案因为没有衡量总体积的变大的方法
#include <iostream>
#include <math.h>
using namespace std;
#define MAX_N 10
static struct Point
{
int x,y,z;
}Pts[MAX_N];
static int used[MAX_N];
static double userR[MAX_N];//已经放置的球的半径
static int n;
static int box[MAX_N];
static double maxAns = 0.0;
static double pi = acos(-1.0);
static double Distance(Point p1,Point p2)
{
return sqrt((double)(p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.x-p2.z));
}
static double findNearst(int index)
{
double mindis = 0x3f3f3f3f;
double dif;
for (int i=0;i<6;++i)
{
if (i%3==0)
dif = abs(Pts[index].x - box[i]);
else if (i%3==1)
dif = abs(Pts[index].y - box[i]);
else
dif = abs(Pts[index].z - box[i]);
if (dif<mindis)
mindis = dif;
}
//寻找已经安置了的气球
for (int i=0;i<n;++i)
{
if (used[i])//如果已经放置了
{
double r = userR[i];
if (r<0)continue;
dif = Distance(Pts[index],Pts[i]) - r;
if (dif<mindis)
mindis = dif;
}
}
return mindis;
}
static void placeBall(int cur,double curAns)//当前放置的第几个
{
if (cur==n)
{
if (curAns>maxAns)
maxAns = curAns;
return;
}
for (int i=0;i<n;++i)
{
if (!used[i])
{
double r = findNearst(i);//查看当前可以扩展的半径
used[i] = 1;
userR[i] = r;
if (r>0)
placeBall(cur+1,curAns+ (4.0/3.0)*pi*r*r*r);
else
placeBall(cur+1,curAns);
used[i] = 0;
userR[i] = 0.0;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
double volum;
for(int i=0;i<6;++i)
scanf("%d",&box[i]);
volum = abs(box[3]-box[0])*abs(box[4]-box[1])*abs(box[5]-box[2]);
for (int i=0;i<n;++i)
scanf("%d %d %d",&Pts[i].x,&Pts[i].y,&Pts[i].z);
memset(used,0,sizeof(used));
memset(userR,0,sizeof(userR));
maxAns = 0.0;
placeBall(0,0.0);
printf("%.lf\n",volum-maxAns);
}
return 0;
}
FZU1515盒子中的气球,枚举法
最新推荐文章于 2018-05-27 19:36:00 发布