看到这个题,很快的就敲出了全排列的递归程序,结果一直WA。。。。
看人家的代码都没看明白,直到看到人家的解释才懂了。。。无语。。。
原来自己想的情况太理想化了,没有考虑到特大圆,与特小圆存在的特例。
如果一味的按照顺序相切下去,有可能存在与前面的大圆相交的情况。
代码是在原来基础上改的,先贴以一下吧。
代码如下:
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
double radii[10], recoder[10], MIN;
int comp(const void *a, const void *b)
{
return *(double*)a>*(double*)b;
}
double return_length(double a, double b)
{
return sqrt((a+b)*(a+b)-(a-b)*(a-b));
}
void cacultor(int n, int cur)
{
if(cur==n)
{
double max = 0;
for(int i = 0; i < n; i++) max = max<recoder[i]+radii[i]?recoder[i]+radii[i]:max;
if(MIN<0||MIN>max)MIN = max;
return;
}
double diet;
for(int i = 0; i < cur; i++)
{
diet = return_length(radii[i],radii[cur])+recoder[i];
if(diet>recoder[cur]) recoder[cur] = diet;
}
cacultor(n, cur+1);
}
int main ()
{
int t, n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0; i < n; i++) scanf("%lf",&radii[i]);
qsort(radii,n,sizeof(radii[0]),comp);
MIN = -1;
do
{
for(int i = 0; i < n; i++) recoder[i] = radii[i];
cacultor(n, 1);
}
while(next_permutation(radii,radii+n));
printf("%.3lf\n",MIN);
}
return 0;
}