刘汝佳黑书上第一题,看起来简单,但是WA了无数次
基本思路就是枚举放置气球的顺序 然后依次放气球
需要注意的是:枚举的当前点不会被未枚举的点影响,而且也不会被前面计算出半径R为0的点影响,半径为0的点相当于没有放进去
输出时 要用printf("%.0lf\n",ans); 如果用cout 会输出科学计数法 然后就一直WA 一直WA。。。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define Pi acos(-1.0)
using namespace std;
struct Point
{
double x,y,z;
};
Point a[6];
double a1,a2,a3,b1,b2,b3,r[6];
long n,xu[6];
bool exist[6];
double ans=0;
const double maxn=1e9;
double dist(int i,int j)
{
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)+(a[i].z-a[j].z)*(a[i].z-a[j].z));
}
double distoedge(int i)
{
double dis1,dis2,dis3;
dis1=min(fabs(a1-a[i].x),fabs(b1-a[i].x));
dis2=min(fabs(a2-a[i].y),fabs(b2-a[i].y));
dis3=min(fabs(a3-a[i].z),fabs(b3-a[i].z));
return min(dis1,min(dis2,dis3));
}
void out()
{
double rr=0;
for(int i=0;i<n;i++)
{
double dis=maxn;
for(int j=0;j<i;j++)
{
dis=min(dis,dist(xu[i],xu[j])-r[xu[j]]);
}
dis=min(dis,distoedge(xu[i]));
if(dis<0)dis=0;
r[xu[i]]=dis;
rr+=dis*dis*dis;
}
ans=max(ans,rr);
}
void search(long xx)
{
if(xx==n){out();return;}
for(int i=0;i<n;i++)
if(exist[i])
{
xu[xx]=i;
exist[i]=0;
search(xx+1);
exist[i]=1;
}
}
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
long flag=0;
cin>>n;
while(n!=0)
{
ans=0;
flag++;
cin>>a1>>a2>>a3;
cin>>b1>>b2>>b3;
for(int i=0;i<n;i++)cin>>a[i].x>>a[i].y>>a[i].z;
memset(exist,1,sizeof(exist));
memset(r,0,sizeof(r));
search(0);
cout<<"Box "<<flag<<": ";
printf("%.0lf\n",(fabs(a1-b1)*fabs(a2-b2)*fabs(a3-b3)-(double)4.0/3*Pi*ans));//!!!不能用cout 否则为科学计数法
cout<<endl;
cin>>n;
}
return 0;
}