洛谷 P2440 木材加工

这篇博客探讨了一个环保主题下的数学问题,如何将木材厂的原木高效切割成等长小段。通过二分查找算法,确定能最大化小段木头长度的切割方案。输入包括原木数量和所需小段数量,输出是最大可能的木头长度。博客提供了代码示例,展示了如何处理大整数并避免溢出,以及如何优化区间选择以简化实现。
摘要由CSDN通过智能技术生成

题目背景

要保护环境

题目描述

木材厂有 n 根原木,现在想把这些木头切割成 k 段长度均为l的小段木头(木头有可能有剩余)。

当然,我们希望得到的小段木头越长越好,请求出 l 的最大值。

木头长度的单位是cm,原木的长度都是正整数,我们要求切割得到的小段木头的长度也是正整数。

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

输入格式

第一行是两个正整数 n,k,分别表示原木的数量,需要得到的小段的数量。

接下来 n 行,每行一个正整数Li​,表示一根原木的长度。

输出格式

仅一行,即 l 的最大值。

如果连1cm 长的小段都切不出来,输出 0

输入输样例

输入 #1

3 7
232
124
456

输出 #1

114

1<=n<=100000 1<=k<=100000000 1<=Li<=100000000

分析

需要注意使用long long或unsigned long来定义(测试点里有几个很大的数据,用int可能会爆)

二分:

取中点,然后判断 分出的段数 与 输入小段的数量k 的大小。

如果大于等于就在左边,否则右边

bool aa(unsigned long mid)
{
    unsigned long sum=0;
    for(int i=0; i<n; i++)
        sum+=a[i]/mid;
    return sum>=k;
}

在选择区间时最好选择最大的那个,否则要分好几种情况,有点麻烦。

代码

#include <iostream>
#include<algorithm>
#define q 100005
using namespace std;
typedef unsigned long ll;  //类型定义
unsigned int a[q],n;
ll k;
bool cmp(int a,int b)
{
    return a>b;              //使sort从大到小排列
}
bool aa(ll mid)
{
    ll sum=0;
    for(int i=0; i<n; i++)      //判断
        sum+=a[i]/mid;
    return sum>=k;
}
int main()
{
    cin>>n>>k;
    for(int i=0; i<n; i++)
        cin>>a[i];
    sort(a,a+n,cmp);      //最简单是用max()来求其中最大木头长度
    int left=0;
    ll right=a[0];
    unsigned int mid=a[0]/2;
    while(left+1<right)
    {
        mid=(left+right)/2;
        if(aa(mid))left=mid;      //二分
        else right=mid;
    }
    cout<<left;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值