1 条题解
-
2
一、思路分析
1. 核心问题拆解
- 自然晒干:所有衣服同时进行,每秒每件衣服减少
a点湿度(无额外成本)。 - 烘衣机烘干:同一时间只能烘1件,每秒让当前衣服额外减少
b点湿度(总减少a+b点),本质是「串行补充烘干」。 - 目标:找到最小时间
t,使得所有衣服的湿度在t秒内降至0。
2. 关键观察(二分答案的合理性)
- 单调性:若时间
t能烘干所有衣服,则任何t' > t一定也能(时间越充裕,越容易完成)。 - 二分性:存在最小的
t_min,使得t >= t_min时都能完成,t < t_min时无法完成。因此可通过「二分查找」高效找到t_min。
3. 校验函数
check(t)设计(核心逻辑)给定时间
t,判断能否烘干所有衣服:- 对每件衣服,先计算「自然晒干的最大湿度减少量」:
t * a。 - 若衣服湿度
w[i] <= t*a:无需烘衣机,自然晒干即可,跳过。 - 若
w[i] > t*a:需要烘衣机补充烘干,所需烘衣时间为(w[i] - t*a + b - 1) / b(向上取整公式,避免浮点数运算)。 - 累加所有衣服的烘衣时间总和:若总和
<= t,说明烘衣机在t秒内可串行处理完所有需求,返回true;否则返回false。
4. 二分查找边界
- 左边界
l:最小可能时间(初始为1)。 - 右边界
r:最大可能时间(因w[i] <= 5e5,a >=1,最坏情况无需烘衣机时,最大时间为5e5,故设r=5e5+10足够覆盖所有情况)。
二、带详细注释的代码
#include<bits/stdc++.h> using namespace std; const int N = 5e5 + 10; // 数组最大容量,适配数据范围(n<=5e5) int n, a, b; // n:衣服件数;a:自然晒干速率;b:烘衣机额外烘干速率 int w[N]; // 存储每件衣服的初始湿度 // 校验函数:判断时间x是否能烘干所有衣服 bool check(int x) { int total_dryer_time = 0; // 所有衣服所需的总烘衣机时间(串行) for (int i = 1; i <= n; ++i) { // 1. 计算自然晒干x秒后的剩余湿度:若<=0,无需烘衣 int natural_dry = x * a; if (w[i] <= natural_dry) { continue; } // 2. 需烘衣机处理的湿度:总湿度 - 自然晒干的湿度 int need_dry = w[i] - natural_dry; // 3. 计算该衣服所需烘衣时间(向上取整:(x+y-1)/y 等价于 ceil(x/y)) int dryer_time = (need_dry + b - 1) / b; // 4. 累加总烘衣时间,若超过x秒,直接返回false(烘衣机忙不过来) total_dryer_time += dryer_time; if (total_dryer_time > x) { return false; } } // 所有衣服的总烘衣时间 <= x,x秒足够 return true; } int main() { // 读入输入数据 cin >> n >> a >> b; for (int i = 1; i <= n; ++i) { cin >> w[i]; } int l = 1; // 二分左边界:最小可能时间 int r = 5e5 + 10; // 二分右边界:最大可能时间(覆盖所有情况) int ans; // 存储最终答案(最小时间) // 二分查找核心循环 while (l <= r) { int mid = l + r >> 1; // 计算中间时间(等价于 (l+r)/2,避免溢出) if (check(mid)) { // 若mid秒足够,尝试找更小的时间 ans = mid; // 记录当前有效时间 r = mid - 1; // 向左收缩查找范围 } else { // 若mid秒不够,需要更长时间 l = mid + 1; // 向右收缩查找范围 } } // 输出最小时间 cout << ans << endl; return 0; }三、代码关键细节解释
-
向上取整公式:
(need_dry + b - 1) / b
例:need_dry=3,b=2→(3+2-1)/2=4/2=2(正确,需2秒);need_dry=4,b=2→(4+2-1)/2=5/2=2(正确,需2秒)。避免使用浮点数ceil(),提升效率。 -
二分查找效率:
二分查找的次数为log2(5e5) ≈ 19次,每次check函数遍历n件衣服(O(n)),总时间复杂度O(n log M)(M为最大可能时间),适配n=5e5的数据范围,不会超时。 -
边界处理:
右边界设为5e5+10是因为:当a=1、w[i]=5e5时,仅自然晒干就需要5e5秒,加10是为了避免极端情况溢出。 -
样例验证:
样例输入:3 2 1,w=[1,3,4]- 检查
t=2:自然晒干2*2=4点湿度。- 1≤4 → 无需烘衣;3≤4 → 无需烘衣;4≤4 → 无需烘衣。总烘衣时间=0≤2 →
check(2)=true。
- 1≤4 → 无需烘衣;3≤4 → 无需烘衣;4≤4 → 无需烘衣。总烘衣时间=0≤2 →
- 检查
t=1:自然晒干2*1=2点湿度。- 4>2,需烘衣
4-2=2点,烘衣时间=2秒,总烘衣时间=2>1 →check(1)=false。
故最小时间为2,与样例输出一致。
- 4>2,需烘衣
- 检查
- 自然晒干:所有衣服同时进行,每秒每件衣服减少
- 1
信息
- ID
- 1231
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 380
- 已通过
- 83
- 上传者