当前位置:首页 > 题解目录 > 正文内容

【题解】木材加工

亿万年的星光4年前 (2022-03-19)题解目录2792

【题目描述】

 木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有剩余),需要得到的小段的数目是事先给定的,切割时希望得到的小段越长越好。
      编写程序,输入原木的数目 N 和需要得到的小段的数目 K以及各段原木的长度,计算能够得到的小段木头的最大长度。
      木头长度的单位是 cm。原木的长度都是正整数,要求切割得到的小段木头的长度也是正整数。

例如有两根原木长度分别为11和21,要求切割成到等长的6段,很明显能切割出来的小段木头长度最长为5.

【输入描述】

第一行是两个正整数N和K(1 ≤ N ≤ 100000,1 ≤ K ≤ 100000000),N是原木的数目,K是需要得到的小段的数目。

接下来的N行,每行有一个1到100000000之间的正整数,表示一根原木的长度。

【输出描述】

能够切割得到的小段的最大长度。如果连1cm长的小段都切不出来,输出”0”。

【样例输入】

3 7
232
124
456

【样例输出】

114

注: 请对比  切割钢管 这道题目


【题目分析】

采用二分法进行解决(最大化平均值问题)。
      设left是切割的小段木头的最短长度,right是最大长度,初始时,left为0,right为最长的原木长度加1。
      每次取left和right的中间值mid(mid = (left + right) / 2)进行尝试,测试采用当前长度mid进行加工,能否切割出需要的段数K,测试算法描述为:

   num = 0;
      for (i = 0; i < n; i++)
      {
            if (num >= k) break;
            num = num + len[i] / mid ;
      }

    如果当前mid值可以加工出所需段数(即num >= k),说明当前mid值偏小,可能有余量,就增大mid值继续试(通过让left = mid的方法来增大mid);不符合要求,当前mid值加工不出所需段数,显然mid偏大了,就减小mid值继续试(通过让right = mid的方法来减小mid)。直到left +1>= right结束尝试,所得的left值就是可以加工出的小段木头的最大长度。

【参考代码】

#include <iostream>
using namespace std;
int main()
{
      int n, k, len[10000], i, left, right, mid,num;
      cout<<"请输入原木的数目 N 和需要得到的小段的数目 K :"<<endl;
      cin>>n>>k;
      right = 0;
      cout<<"请输入各段原木的长度:"<<endl;
      for (i = 0; i < n; i++)
      {
            cin>>len[i];
            if (right < len[i]) right = len[i];
      }
      right++;
      left = 0 ;
      while ( left + 1 < right)
      {
            mid = (left + right) / 2;
            num = 0;
            for (i = 0; i < n; i++)
            {
                  if (num >= k) break;
                  num = num + len[i] / mid ;
            }
            if ( num >= k )
                  left = mid;
            else
                  right = mid;
       }
      cout<<"能够切割得到的小段的最大长度为 "<<left<<endl;
      return 0;
}


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    标签: 二分
    分享给朋友:

    相关文章

    数列

    数列

    【题目描述】有一个分数序列求出这个序列的前n项和,结果保留两位小数。(注意,不用通分,单项相加即可)【输入描述】一个数字,N【输出描述】前N项的和【样例输入】10【样例输出】16.48【题目分析】(1...

    【题解】石子合并

    【题目描述】在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。设计一个程序,计算出将N堆石子合并成一堆的...

    【题解】切比雪夫距离

    【题目描述】小C有一个平面!它发现了平面上的两个点,请你求出求它们之间的切比雪夫距离。切比雪夫距离定义为x与y方向坐标差的绝对值较大值。【输入描述】四个整数,a,b,c,d。坐标为(a,b)与(c,d...

    【题解】游览动物园

    【题目描述】动物园有很多游览区,小红已经在动物园的一个游览区游览,突然接到电话,要半个小时内到动物园外面跟一个朋友见面。半个小时小红只够游览完当前区域之后,游览一个最近的景区。已知从一个游览区域只能沿...

    【题解】小X与机器人

    【题解】小X与机器人

    【题目描述】小X的老师很喜欢围棋。众所周知,围棋的棋盘有19行19列,共有361个交叉点。为方便起见,我们把这些行列按顺序编号为1~19,并用(x, y)表示第x列第y行的位置。例如下图中,A用(16...

    【题解】变换数组

    【题目描述】输入一个数组 a,包含有 n 个元素 a1,a2,⋯,an。对这个数组进行 m 次变换,每次变换会将数组 a ...