栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

枚举算法实践2-切割木棍 c++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

枚举算法实践2-切割木棍 c++

题目描述

我们有n根的木棍。现在从这些木棍中切割出来m条长度相同的木棍,问这m根木棍最长有多长?

输入数据
  • 第一行输入两个数字,n和m
    n(1<=n<=1000)为木棍数目
    m(1<=m<=1000)为需要切割出的相同长度的木棍数目
  • 随后n个正整数,表示原始木棍的长度(<=10000)
输出数据

每组输出一行结果,表示切割后绳子的最长长度(保留两位小数)

样例输入
4 5
5 6 7 8
样例输出
4.00
初始思路
  • 因为要求切割的最大长度,本来想着从木棍长度中找到最大的长度,不断递减向下寻找,直到能切割的数目>= m。!不过不可以,因为切割的长度极有可能不为整数。
正解思路
  • 明确切割木棍的长度最粗略的范围就是0到当前木棍中最长的那个
  • 明确范围之后,我们就可以使用二分查找了
  • 每一次查找要计算 以当前mid指向的长度 切割的 木棍数目num
  • 若num 大于等于m(想要的数目) 说明木棍长度小了 所以要更新left为mid
  • 反之 更新 right 为mid
  • 直到left 等于right时,就找到了满足当前条件的最长的切割长度了
代码
#include 
#include 
#include 
#include 
#include  //round四舍五入
using namespace std;
int main()
{
    int n, m;
    vector lens;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        int temp;
        cin >> temp;
        lens.push_back(temp);
    }
    auto max = max_element(lens.begin(), lens.end()); //max_element 返回的是迭代器
    double l = 0, r = *max;                           //能切割的木棒长度 最粗略的范围就是0到当前木棒中最大的
    double mid;
    while (l + 0.01 < r) //不断更新范围 直到 l = r = 最佳解
    {
        int num = 0;
        mid = round(((l + r) / 2.00) * 100) / 100.00; //保证精度
        // float middd = round(l + r) / 2.00;            //不可以 (4+4.5)=4.5
        for (int i = 0; i < n; i++)
            num += (int)(lens[i] / mid); //针对当前长度 看每个lens能切割成多少个
        if (num >= m)                    //当前的切割 得到的木棍多 说明当前的切割长度小了
            l = mid;
        else
            r = mid;
    }
    printf("%.2f", l);
    system("pause");
    return 0;
}
补充
  • mid = round(((l + r) / 2.00) * 100) / 100.00; 为了保证精度到小数点后两位
  • num += (int)(lens[i] / mid); 因为木棍切割只能向下取整,所以int的除法刚好合适
  • max_element() 返回容器中最大值的迭代器,所以输出值的话要对其取 *
  • 对于格式化的输入和输出,scanf 和 printf更方便
  • 若文章存在问题,还请各位大佬批评指正,共同进步。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/657059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号