/*
暴力枚举,模拟放入圆。 半径为R1、R2的两个圆相切,通过勾股定理推出,两圆心的水平距离为 2sqrt(R1*R2)
注意到对一些特殊情况处理,如例子 4 1000.0 1.0 1.0 1.0
最坏时间复杂度为 8!,其实可以优化成 8!/2, 因为排序1、2、3 和 排序3、2、1求出来的值是相等的。
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX = 8+2;
int m;
double r[MAX]; //半径
double min_len;
double get_len()
{
double c[MAX]; //圆心坐标,以箱子左边为原点
double max_c;
double len = 0;
for(int i=0; i<m; i++) {
max_c = r[i];
for(int j=0; j<i; j++) {//分别求出第i个圆和前i-1个圆相切时i圆心的坐标,取最大的i圆心坐标
double k = 2 * sqrt(r[i]*r[j]); // k 为第i个圆心和第j个圆心的水平距离
if(k+c[j] > max_c) max_c = k+c[j];
}
c[i] = max_c;
if(c[i] + r[i] > len) len = c[i] + r[i];
}
return len;
}
int main(void) {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int n;
scanf("%d", &n);
while(n--) {
scanf("%d", &m);
if(m<=0) continue;
for(int i=0; i<m; i++) {
scanf("%lf", &r[i]);
}
min_len = 10e8;
sort(r, r+m);
do{
double temp = get_len();
if(temp < min_len) min_len = temp;
}while(next_permutation(r, r+m));
printf("%.3lf\n", min_len);
}
return 0;
}
UVa 10012 - How Big Is It?
最新推荐文章于 2019-03-13 05:26:33 发布