UVA10012

来源:互联网 发布:淘宝客进入等级 编辑:程序博客网 时间:2024/04/30 03:06

Ian打算要去的加州,他要收拾东西,包括他收集的圆圈,给定一组圆圈,你的程序必须找到的最小矩形以放下所有的园。每个园必须接触盒子的底部。下图显示了一个例子(尽管这可能不是最佳的包装方案)。请注意,在一个理想的包装,每个圆至少应该接触一个圆(但你可能明白了)。

输入的第一行包含一个的十进制正整数n,n < = 50。N指出了接下来的行数。接下来的n行每一个包含一系列用空格分开的数字。第一个数字m ,m < = 8,这表明有多少个圆。接着是m个圆的半径。

程序输出可以把圆圈包装起来的最小矩形的大小,保留到小数点后三位。不要输出前导零,除非数量小于1,例如0.543

题意给你一些圆的的半径把它们放在一个矩形里

每个圆底部着地

求矩形的长最短的长度

枚举全排列就好

1有可能有的圆很大有的圆很小而使相邻圆不接触

这就要记录每个圆的圆心,并判断当它与前面所有圆都相切时的最大距离;

2错了好几次才注意到当前面的圆都很小时,这个圆于前面的圆都相切时有可能有一部分越过左边界

#include <iostream>#include<cmath>#include<algorithm>#include<cstring>#include<iomanip>#include<cstdio>//#define LOCAL#define P  3.141579269596using namespace std;int mark[8] ,n,m;double a[8],A[8],MIN=10000000000;double js(){    double d[10]={0};    d[0]=A[0];    double MAX=2*A[0];    for(int i=1;i<m;i++)        for(int j=0;j<i;j++)    {        double D=d[j]+2*sqrt(A[j]*A[i]);        D=max(D,A[i]);        d[i]=max(D,d[i]);        MAX=max(d[i]+A[i],MAX);    }    return MAX;}void dfs(int cur){    if(cur==m)    {        double d=js();        if(d<MIN) MIN=d;    }    else for(int i=0;i<m;i++)        if(!mark[i])    {        mark[i]=1;        A[cur]=a[i];        dfs(cur+1);        mark[i]=0;    }}int main(){    #ifdef    LOCAL    freopen("input.txt","r",stdin);    #endif // LOCAL    cin>>n;    while(n--)    {        cin>>m;        for(int i=0;i<m;i++)  cin>>a[i];        dfs(0);        printf("%.3lf",MIN);        cout<<endl;        MIN=10000000000;        memset(mark,0,sizeof(mark));    }    return 0;}


0 0
原创粉丝点击