1 条题解
-
0
题意分析
题目背景
本题属于二分查找与数值优化问题,描述如何从给定长度的电缆中切割出指定数量的等长电缆段,并最大化每段长度。
核心问题
- 输入数据:
- :库存电缆数量()。
- :所需电缆段数量()。
- 每根电缆的长度(,精度到厘米)。
- 目标:找到满足段切割条件的最大电缆段长度(以厘米为单位,保留两位小数)。
约束条件
- 切割后的每段长度必须。
- 若无法满足段,输出
0.00
。
解题思路
1. 问题转换
- 单位统一:将所有电缆长度转换为厘米(乘以),避免浮点数运算。
- 数学建模:设最大长度为,则需满足:$$\sum_{i=1}^{N} \left\lfloor \frac{\text{length}_i}{L} \right\rfloor \geq K $$其中为第根电缆的长度。
2. 二分查找
- 搜索范围:
- 左边界。
- 右边界。
- 可行性检查:
对于中间值,计算是否能切割出至少段长度为的电缆。
- 若可行,尝试更大的(调整)。
- 否则,尝试更小的(调整)。
- 终止条件:,找到最大可行。
3. 边界处理
- 无解情况:若或所有电缆总长度不足,直接输出
0.00
。
算法实现
代码框架
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,k; int a[10005]; bool cheak(int l) { ll sum=0; int i; for(i=1;i<=n;i++) { sum+=a[i]/l; } return sum>=k; } int main() { cin>>n>>k; int i; double t; for(i=1;i<=n;i++) cin>>t,a[i]=int(t*100); if(cheak(1)==false) { cout<<"0.00"; return 0; } int l = 1,r = 1e7; int mid; while(l<r) { mid = (l+r+1)/2; if(cheak(mid)) l = mid; else r = mid-1; } printf("%.2f",(double)l/100); return 0; }
关键步骤
- 输入处理:读取电缆数量和需求,转换长度为厘米。
- 可行性检查:函数
isFeasible
验证当前长度是否满足段需求。 - 二分查找:
- 初始化边界,。
- 循环调整边界,直到找到最大可行。
- 输出结果:将转换回米单位并格式化输出。
复杂度分析
- 时间:,其中二分查找迭代次数为,每次检查。
- 空间:,存储电缆长度。
- 输入数据:
- 1
信息
- ID
- 65
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者