当前位置: 首页 > article >正文

圆排列C++

Description

给定n个大小不等的圆c1,c2,…,cn,现要将这n个圆排进一个矩形框中,且要求各圆与矩形框的底边相切。圆排列问题要求从n个圆的所有排列中找出有最小长度的圆排列。例如,当n=3,且所给的3个圆的半径分别为1,1,2时,这3个圆的最小长度的圆排列如下图所示。(注意,只要求圆和矩形框底边相切,不要求相邻圆都相切)

图片1.png

Input

输入为两行,第一行为一个整数n,即圆的个数;第二行为n个数,即圆的

Output

输出为一个浮点数,取到小数点后2位,即圆排列的最小长度

Sample Input 1 

3
1 1 2

Sample Output 1

7.65

思路

他只给出半径,没给顺序,所以给他来个全排列。

假设大的圆的半径x,小的圆的半径y

根据勾股定理,那么矩形底边的那段长就是(x+y)*(x+y)-(x-y)*(x*-y)然后开根号

把所有这样的结果(1到2,2到3····一直到n-1到n)全部加起来,再加上第一个和最后一个圆的半径,就是底边的长了。

然后取最小的。还没剪枝就过了。。。。

好像是可以用剪枝来优化,(代码里没有)如果当前的排列的底边已经大于已经求得的最小值了,

那么可以直接剪枝(直接跳过该排序)

代码

#include<bits/stdc++.h>
using namespace std;
int n;
int r[1000];//存放半径

double calculate(int r[],int n,double minL){
    double x,y;//表示两个圆的半径
    double sum=0;
    for(int i=1;i<n;i++){
        //取大的半径为x,小的为y
        if(r[i]>r[i+1]){
            x=r[i];
            y=r[i+1];
        }else{
            y=r[i];
            x=r[i+1];
        }
        //两个圆的矩形边方向的距离
        sum+= sqrt((x+y)*(x+y)-(x-y)*(x-y));
    }
    sum+=r[1]+r[n];//加上开头和结束
    minL=min(minL,sum);
    return minL;
}

int main(){
    cin>>n;
    double ans=DBL_MAX;//取一个无穷大
    for(int i=1;i<=n;i++){
        cin>>r[i];
    }
    do{
        ans=calculate(r,n,ans);
    }while(next_permutation(r+1,r+n+1));//全排列
    printf("%.2f",ans-0.005);//减去0.005来进行浮点数精度修正
}


http://www.kler.cn/a/454910.html

相关文章:

  • HMSC联合物种分布模型
  • 集星獭 | 集成能力之消息队列集成
  • CSS学习记录19
  • 使用 ABAP 进行应用程序日志记录
  • 桥接模式详解
  • 后端项目打包发布
  • 湖南科技大学-计算机学院-毕业设计选题详细信息(2024)
  • 智慧农业应用场景|珈和科技农业调查解决方案
  • LaTeXChecker:使用 Python 实现以主 TEX 文件作为输入的 LaTeX 检查和统计工具
  • C#控件开发3—文本显示、文本设值
  • Ubuntu 22.04.5 修改IP
  • 面试突击-JAVA集合类(持续更新...)
  • 【SQL】筛选某一列字段中,截取含有关键词“XX”字段位置的前4个字段,去重后查看字段
  • PDF书籍《手写调用链监控APM系统-Java版》第11章 插件与链路的结合:HttpClient插件实现跨进程传输TraceSegment
  • OpenCV-Python实战(8)——图像变换
  • 探索基金聚合平台的背景与发展:Finanzen.net、Franklin Templeton、Finect
  • STM32完全学习——FATFS0.15移植SD卡
  • AI客服机器人如何帮助企业应对高峰期客户咨询压力?
  • LeetCode--239.滑动窗口最大值(使用双端队列解决)
  • docker拉取rabbitmq镜像时报Client.Timeout exceeded while awaiting header错误处理办法