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://s2.ax1x.com/2019/05/26/VE5YD0.jpg)
更多内容请关注个人微信公众号 物役记 (微信号:materialchains)
作者:雪影蓝枫
本文版权归作者和博客园共有,欢迎转载,未经作者同意须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。