uva10012 - How Big Is It?

想到可能存在两个半径很大的圆相切,中间夹着很多小的圆(这样单纯的全排列只判断相邻两圆的话就可能出现圆圆相交的情况),这样就需要加为每个已经判断过的圆加个坐标,对于正在判断的圆,与前面所有判断是否相交,若相交以这两个圆为相邻圆,求当前圆坐标。

#include <iostream>
#include <cstring>
#include<cstdio>
#include<cstdlib>
#include <string>
#include<algorithm>
#include<cmath>
//#define MARK -2147483647
using namespace std;
double cir[10];int pai[10]={0,1,2,3,4,5,6,7,8,9}; int m;double ans=0;
struct yuanxin
{
double x,y;
};
double qiulong( )
{   yuanxin yuan[10];
    double ll =0;
    int i;
    yuan[0].x=0.0;yuan[0].y=cir[pai[0]];
    for(i=0;i<m-1;++i)
    {   double llshi=ll;
        //cout<<cir[pai[i]]<<cir[pai[i+1]]<<endl;
        llshi=llshi+sqrt((cir[pai[i]]+cir[pai[i+1]])*(cir[pai[i]]+cir[pai[i+1]])-(cir[pai[i]]-cir[pai[i+1]])*(cir[pai[i]]-cir[pai[i+1]]));
        //cout<<i<<"e"<<llshi<<endl;
        yuan[i+1].x=llshi;yuan[i+1].y=cir[pai[i+1]];
        for(int ii=i-1;ii>=0;--ii)
        {
            double bil=sqrt((yuan[ii].x-yuan[i+1].x)*(yuan[ii].x-yuan[i+1].x)+(yuan[ii].y-yuan[i+1].y)*(yuan[ii].y-yuan[i+1].y));
            if(bil-(cir[pai[ii]]+cir[pai[i+1]])<-(1e-6))
            {ll=yuan[ii].x+sqrt((cir[pai[ii]]+cir[pai[i+1]])*(cir[pai[ii]]+cir[pai[i+1]])-(cir[pai[ii]]-cir[pai[i+1]])*(cir[pai[ii]]-cir[pai[i+1]]));llshi=ll;yuan[i+1].x=llshi;   }
        }//cout<<i<<"e"<<llshi<<endl;
        ll=llshi;
    }
    ll=ll+cir[pai[m-1]];
    for(int ii=m-2;ii>=0;--ii)
    {
        if(ll-(yuan[ii].x+cir[pai[ii]])<-(1e-6))ll=yuan[ii].x+cir[pai[ii]];
    }
    double bii=-cir[pai[0]];
     for(int ii=m-1;ii>=0;--ii)
    {
        //if(ll-(yuan[ii].x+cir[ii])<-(1e-6))ll=yuan[ii].x+cir[ii];
        if(bii-(yuan[ii].x-cir[pai[ii]])>1e-6) bii=yuan[ii].x-cir[pai[ii]];
    }
    return ll-bii;
}
int main()
{
// freopen("in.txt","r",stdin);
    int n;scanf("%d",&n);
    while(n--)
    {

        scanf("%d",&m);
        int i;ans=0;
        for(i=0;i<m;++i)
        {
            scanf("%lf",&cir[i]);
            ans+=2*cir[i];
        }
        do
        {
            double ll=qiulong();
            if((ll-ans)<-(1e-6)) ans=ll;
        }while(next_permutation(pai,pai+m));
        printf("%.3lf\n",ans);
    }
    return 0 ;
}


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值