您的位置:首页 > 其它

UVA 10012 How Big Is It?

2016-07-27 21:01 507 查看

UVA-10012

题意:给出一堆圆的半径,求要用多长的矩形能把框住。

解题思路:枚举球的排列顺序(next_permutation大法好),然后判断球的圆心的位置应该在哪里。temp[x]表示圆心的位置,temp是和之前所有的圆求圆心位置中取最大值的那个(可能两个很大的圆中间有一堆小的,只和前一个计算圆心位置不够)。

怎么通过一直圆求新圆的圆心位置:r1,r1 d=r1+r2, t=abs(r1-r2) ; temp[new] = temp[i] +sqrt(d*d-t*t).自己画图一下就知道了。

然后一些初始化问题。temp[i] = r[i]。可能新的比较大,直接顶到左边缘了。

dis对于每一个都要 dis = max (dis , temp[x]+r[x]) 可能中间 的就很大,反而到最后面是在其他圆下面。

/*************************************************************************
> File Name: UVA-10012.cpp
> Author: Narsh
>
> Created Time: 2016年07月27日 星期三 16时17分43秒
************************************************************************/

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int n,m,t;
double r[12],dis,Min,temp[12];
void dfs(int x) {
if (x > m) return ;
for (int i = 1; i < x; i++) {
double d = r[x]+r[i],l=r[x]-r[i];
if (l < 0) l = -l;
temp[x] = max(temp[x] , temp[i]+sqrt(d*d-l*l));
}
if (temp[x] + r[x] >dis) dis = temp[x]+r[x];
dfs(x+1);
}
int main() {
scanf("%d",&t);
while (t--) {
scanf("%d",&m);
for (int i = 1; i <= m; i++)
scanf("%lf",&r[i]);
sort(r+1,r+1+m);
Min = 99999999.099;
do {
dis=2*r[1];
for (int i = 1; i <= m; i++) temp[i] = r[i];
dfs(2);
if(dis < Min) Min = dis;
}while (next_permutation(r+1,r+1+m));
printf("%.3lf\n",Min);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: