Uva 10012 - How Big Is It?

  How Big Is It? 

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=953

题目要求你求一个足以容纳所有给你不同半径的圆的矩阵尽可能短的长,一开始看到AC率就知道没那么简单,所以不考虑其他,仅仅计算全排列的前提下所有两圆相切累加后的最短长度,提交上去WA了,然后考虑了一段时间,觉得有可能会出现这种情况:

如果左边的圆不会这么大的时候,那么蓝色的线(半径)就不一定比红色的那条长了,见右图

 

   

所以仅仅根据半径计算两圆之间的距离是不行的,像右边的这种情况,只要处理了就没问题了,我这里是用另外一个数组,计算给出没一个圆实际的放置位置,每次都判断有无这中情况出现,最后算出这次排列需要的最小矩形的长,然后跟之前排列记录的最小矩形长进行比较

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath> 
 4 #include<cstring>
 5 #include<algorithm>
 6 #define MAXN 10
 7 #define INF 0x7FFFFFFF
 8 using namespace std;
 9 double circle[MAXN], actually[MAXN];
10 double minlen;
11 
12 double dis(double left, double right)
13 {
14     double a, c;
15     c = left + right;
16     a = fabs(left - right);
17     return sqrt(c * c - a * a);
18 }
19 
20 void Traverse(int n)
21 {
22     double len = 0;
23     actually[0] = circle[0];
24     for(int i=1; i<n; ++i)
25     {
26          actually[i] = circle[i];
27          for(int j=0; j<i; ++j)
28          {
29              double temp = dis(circle[j], circle[i]) + actually[j];
30              if(temp > actually[i])  actually[i] = temp;
31           }
32     }
33     double temp = -INF;
34     for(int i=0; i<n; ++i)
35     {
36         if(actually[i] + circle[i] > temp)
37         temp = actually[i] + circle[i];
38     }
39     if(temp < minlen) minlen = temp;
40     return;
41 }
42 
43 int main()
44 {
45     #ifndef ONLINE_JUDGE
46     freopen("input.txt", "r", stdin);
47     #endif
48     int T;
49     cin>>T;
50     while(T--)
51     {
52         int n;
53         cin>>n;
54         memset(circle, 0, sizeof(circle));
55         for(int i=0; i<n; ++i)
56             cin>>circle[i];
57         minlen = INF;
58         sort(circle, circle+n);
59         do
60         {
61             Traverse(n);
62         }while(next_permutation(circle, circle+n));
63         printf("%.3lf\n", minlen); 
64     }
65     return 0;
66 } 

 

转载于:https://www.cnblogs.com/liaoguifa/archive/2013/04/27/3047082.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值