T^T ONLINE JUDGE 3313 盒子里的气球

#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;
}

猜你喜欢

转载自www.cnblogs.com/qq136155330/p/9097033.html