2005: 光盘行动(New Online Judge)
题目描述
Alice看到了有很多菜没最后都没有吃完。
本着不浪费的精神,她决定将这些菜打包好分发给各位亲戚带走。
每分钟,Alice可以选择一份菜,填满一个打包盒(如果填不满也不会用其他的菜去补充)。
距离散会还有一段时间,他们希望你计算一下所需打包盒的最小容积
这样既能准时完成所有菜品的打包,也能分成更多份给不同的人。
输入
第一行是样例个数K(1<=K<=1000)。
每组样例的第一行是剩菜的个数N(1<=N<=1000),可用时间T(1<=T<=1000),保证N<=T(即:只要打包盒的容积足够大,就一定能在规定时间内打包完所有的菜)。
第二行N个整数,表示每盘菜的剩余量Ai(1<=Ai<=10000)。
输出
每组样例输出一个数字,即打包盒的最小容量。
样例输入
3
4 8
3 6 7 11
5 6
30 11 23 4 20
5 9
10 11 12 13 14
样例输出
4
23
10
提示信息
题意:一盘菜可以用多个打包盒打包,在规定时间内,打包完所有的菜为止,而填满一个打包盒需要一分钟。因此,本题就是求打包盒的数量小于规定时间的最小打包盒容积
题解1(C++版本)
#include<bits/stdc++.h>
using namespace std;
int k, n, t, a[1010];
bool check(int x){ //打算用容量为x的打包盒打包所有的菜
int cnt = t;
for(int i = 1; i <= n; i++){
cnt -= ((a[i] - 1)/x + 1); //向上取整,比如 a[i] = 3, x = 4, 需要两个打包盒,即(3 - 1)/4 + 1 = 2
if(cnt < 0) return false;
}
return true;
}
int main(){
scanf("%d", &k);
while(k--){
scanf("%d%d", &n, &t);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
int L = 0, R = 1e7 + 1, mid;
while(L + 1 < R){
mid = (R + L)/2;
if(check(mid)) R = mid;
else L = mid;
}
printf("%d\n", R);
}
return 0;
}