小杨在学校义卖会上负责打包“零食盲盒”。每个盲盒重量不同,快递盒最多承重 limit 克,每个快递盒最多装两个盲盒。为了尽量少用快递盒,他采用如下策略:
($1$)每次把最轻的盲盒和最重的盲盒尝试放在一起;
($2$)如果两者重量之和不超过 limit,就一起装;
($3$)否则,只能让最重的盲盒单独装一盒。
下面代码用于计算最少需要多少个快递盒,则横线处应填入的是( )。
int minBoxes(vector<int>& w, int limit) {
sort(w.begin(), w.end());
int l = 0, r = w.size() - 1;
int boxes = 0;
while (l <= r) {
if (w[l] + w[r] <= limit) {
__________; // 在此处填入代码
} else {
r--;
}
boxes++;
}
return boxes;
}STL 容器:vector(动态数组)、set/map(红黑树,有序)、unordered_set/map(哈希表,无序)。注意迭代器失效问题。
填空时注意语法完整性:分号、括号匹配、函数参数类型和个数、返回值类型。
【考点】排序|双指针|条件判断
本题在 GESP 五级“数据结构与算法”模块考查排序与双指针。命题人想卡住只会暴力枚举的考生——五级允许 sort,但不会给 O(n^2) 的暴力匹配,必须用贪心策略。
看到题先想贪心:最轻配最重能省最多空间。排序后 l 指向最轻、r 指向最重。若 w[l]+w[r]<=limit,说明这两个可以同装,必须同时跳过(l++ r--);否则最重的只能单独装(r--)。每轮循环 boxes++ 记录用掉一个盒。这是“双指针贪心配对”通法,可迁移到所有“两两配对求和不超过某值”的题目。
错误选项全是语义陷阱:A 只动 l,若次轻仍过重,会浪费盒;B 只动 r,若次重仍过轻,同样浪费;D 更离谱,每轮都 boxes++,再减回去等于没装盒。最阴险的是“最重必单装”——只有 w[l]+w[r]<=limit 才配对,否则最重只能单独,这直接对应 r-- 且 boxes++。
反命题想:若把“每盒最多两盒”改成“每盒最多三盒”,策略就变成每次取最重的三个尝试配对;若改成“每盒只能装偶数个且重量和为偶数”,贪心策略就失效。刷到同类题先问“命题人想考我什么”,这题就是考双指针贪心配对。