uva 10012 How Big Is It?

来源:互联网 发布:手机淘宝上怎么交电费 编辑:程序博客网 时间:2024/06/05 22:47

题目地址:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=953

题目描述:

How Big Is It? 

Ian's going to California, and he has to pack his things, including his collection of circles. Given a set of circles, your program must find the smallest rectangular box in which they fit. All circles must touch the bottom of the box. The figure below shows an acceptable packing for a set of circles (although this may not be the optimal packing for these particular circles). Note that in an ideal packing, each circle should touch at least one other circle (but you probably figured that out).

Input 

The first line of input contains a single positive decimal integer nn<=50. This indicates the number of lines which follow. The subsequent n lines each contain a series of numbers separated by spaces. The first number on each of these lines is a positive integer mm<=8, which indicates how many other numbers appear on that line. The next m numbers on the line are the radii of the circles which must be packed in a single box. These numbers need not be integers.

Output 

For each data line of input, excluding the first line of input containing n, your program must output the size of the smallest rectangle which can pack the circles. Each case should be output on a separate line by itself, with three places after the decimal point. Do not output leading zeroes unless the number is less than 1, e.g. 0.543.

Sample Input 

33 2.0 1.0 2.04 2.0 2.0 2.0 2.03 2.0 1.0 4.0

Sample Output 

9.65716.00012.657


题意:最小矩形长度放想切圆,求最小长度。

题解:

陷阱:圆与圆并不直接想切,想像 两个很大很大的圆,中间有个很小的圆只与左边的大圆相切,不与右边的大圆相切,这样第二个圆与第三个圆并不相切。

用圆心矩(即相对于矩形的最左边的距离,可以把矩形的最左边设为一维坐标的原点)来计算最小矩形长度。跟据圆心矩找最左坐标 和 最右坐标。然后最右-最左就是最小矩形的长度。不用去关心圆与圆是否直接相切的问题,我们只关心最右与最左坐标。求最左与最右(这体现在代码中求dis的偏大值上),我们可以假设相切算出所有可能的相切情况,然后在每一个全排列的情况下,递推出所有可能的边界值,然后再边界值中找出最大的作为边界,因为最右边界不一定是第n个圆的边界,可能是第j个圆,而这个圆很大达到了最右边界,所有要一直从1到n递推找边界最大的,然后去最小值即可(这体现在对Min取偏小的情况下)。

代码:

/*acm uva How Big Is It? 10012get n circle  between the 0~n-1 circle's max touch distance is the distanceif n match the j  the j -> j+1  j+1 -> j+2  n-1 -> n is non of the bussiness*/#include<stdio.h>#include<stdlib.h>#include<string>#include<algorithm>#include<math.h>using namespace std;int n=0;double Point[8+5]={0};int m=0;double Radii[8+5]={0};double Min=0;/*for test*/int test(){    return(0);}/*main process*/int MainProc(){    scanf("%d",&n);    while(n--)    {        scanf("%d",&m);        int i=0,j=0;        for(i=0;i<=m-1;i++)        {            scanf("%lf",&Radii[i]);        }        sort(Radii,Radii+m);        Min=0;        do        {            Point[0]=Radii[0];            for(i=1;i<=m-1;i++)            {                Point[i]=0;//initialize                for(j=0;j<=i-1;j++)                {                    double dis=Point[j]+sqrt((Radii[i]+Radii[j])*(Radii[i]+Radii[j])-(Radii[i]-Radii[j])*(Radii[i]-Radii[j]));//like the DP                    if(dis>Point[i])                    {                        Point[i]=dis;                    }                }            }            //gei the rightiest  and the leftiest            double left=Point[0]-Radii[0];            double right=Point[0]+Radii[0];            for(i=1;i<=m-1;i++)            {                if(Point[i]-Radii[i]<left)                {                    left=Point[i]-Radii[i];                }                if(Point[i]+Radii[i]>right)                {                    right=Point[i]+Radii[i];                }            }            if(Min==0||Min>right-left)            {                Min=right-left;            }        }while(next_permutation(Radii,Radii+m));        printf("%.3f\n",Min);    }    return(0);}int main(){    MainProc();    return(0);}







原创粉丝点击