csp信奥赛C++高频考点专项训练:【二分答案】案例2:木材加工

csp信奥赛C++高频考点专项训练:【二分答案】案例2:木材加工

题目描述

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

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

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

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

输入格式

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

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

输出格式

仅一行,即 l l l 的最大值。

如果连 1cm \text{1cm} 1cm 长的小段都切不出来,输出 0。

输入输出样例 1
输入 1
复制代码
3 7
232
124
456
输出 1
复制代码
114
说明/提示

对于 100 % 100\% 100% 的数据,有 1 ≤ n ≤ 10 5 1\le n\le 10^5 1≤n≤105, 1 ≤ k ≤ 10 8 1\le k\le 10^8 1≤k≤108, 1 ≤ L i ≤ 10 8 ( i ∈ 1 , n ) 1\le L_i\le 10^8(i\in1,n) 1≤Li≤108(i∈1,n)。

AC代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, k, a[N], ans; // ans保存最终结果,初始为0,符合题目要求的无法切割情况输出0

// 检查能否将原木切割成至少k段,每段长度为x
bool check(int x) {
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        cnt += a[i] / x; // 当前原木可切割出的段数
    }
    return cnt >= k; // 总段数是否满足需求
}

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) cin >> a[i];
    
    int l = 1, r = 1e8, mid; // 二分查找的初始左右边界,最大可能长度为1e8
    
    // 二分查找寻找最大可行长度
    while (l <= r) {
        mid = (l + r) / 2;
        if (check(mid)) { // 当前长度可行,尝试更大的长度
            ans = mid;    // 更新答案
            l = mid + 1;
        } else {          // 当前长度不可行,减小长度
            r = mid - 1;
        }
    }
    
    cout << ans; // 输出结果,若无法切割则为初始值0
    return 0;
}

功能分析

该程序使用二分查找算法确定能够切割出k段等长木头的最大可能长度。具体步骤如下:

  1. 输入处理 :读取原木数量n和目标段数k,以及每根原木的长度。
  2. 二分查找初始化:设定初始左边界为1(最小可能长度),右边界为1e8(最大可能长度)。
  3. 检查函数check :计算给定长度x下所有原木能切割出的总段数,判断是否满足至少k段的需求。
  4. 二分过程:不断调整左右边界,寻找满足条件的最大长度。若当前中间值可行,则尝试更大的长度;否则减小长度。
  5. 结果输出:最终输出找到的最大长度,若无法满足条件则输出初始值0。

该算法高效处理了大范围数据,时间复杂度为O(n log(maxL)),适用于题目给定的数据规模。


完整信奥赛C++普及组CSP-J一等奖通关刷题题单及题解,请关注专栏:

https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转


【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:

https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:

https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:

https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:

https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
xailorliu4 小时前
SLIC_超像素算法
c++·opencv·目标检测·机器学习·计算机视觉
苏打豆4 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
小小龙学IT6 小时前
snap7 开源西门子 S7 通信协议库深度解析
c++·开源
小溪学编程6 小时前
从 C++ 的规范变迁看语言发展
jvm·c++·面试
ShineWinsu7 小时前
对于Redis:string类型的解析
java·c++·redis·分布式·缓存·面试·string
YYYing.8 小时前
【设计模式系列 (七) 】桥接模式
c++·后端·设计模式·桥接模式
高山有多高9 小时前
【Linux笔记】Linux自定义Shell
linux·c++
悠仁さん9 小时前
【C++】vector 类
开发语言·c++
_upupup9 小时前
智能指针的原理及简单模拟实现(C++)
开发语言·c++
l1t9 小时前
DeepSeek总结的OpenZL压缩变换器
c++·算法