题目
机器人搬砖,一共有 N 堆砖存放在 N 个不同的仓库中,第 i 堆砖中有 bricks[i] 块砖头,要求在 8 小时内搬完。
机器人每小时能搬砖的数量取决于有多少能量格,机器人一个小时中只能在一个仓库中搬砖,机器人的能量格只在这一个小时有效,为使得机器人损耗最小化,应尽量减小每次补充的能量格数。
为了保障在 8 小时内能完成搬砖任务,请计算每小时给机器人充能的最小能量格数。
- 无需考虑机器人补充能力格的耗时;
- 无需考虑机器人搬砖的耗时;
- 机器人每小时补充能量格只在这一个小时中有效;
题目输入
第一行为一行数字,空格分隔
题目输出
机器人每小时最少需要充的能量格,若无法完成任务,输出 -1
实例
输入 | 30 12 25 8 19 |
输出 | 15 |
说明 | 无 |
输入 | 10 12 25 8 19 8 6 4 17 |
输出 | -1 |
说明 | 砖的堆数为9堆存放在9个仓库中,机器人一个小时内只能在一个仓库搬砖,不可能完成任务。 |
题目解析
题目
题目代码
#include <iostream>
#include <vector>
using namespace std;
bool check(vector<int>& nums, int mid){
int ans = 0;
for(auto nu:nums){
ans += (nu + mid - 1)/mid;
if(ans > 8) return false;
}
return true;
}
int main(){
int n;
vector<int> nums;
while(cin >> n){
nums.push_back(n);
if(cin.peek() == '\n') break;
}
if(nums.size() > 8){
cout << -1 <<endl;
return 0;
}
sort(nums.begin(), nums.end());
if(nums.size() == 8){// 输出最大值即可。
cout << nums.back() << endl;
return 0;
}
// 对目标结果进行二分法查找
// 明确下限:应该是数组的和/8,向下取整,这个值肯定满足不了。
// 如果不知道怎么计算,就使用最小值0
int sum = 0;
for(auto num:nums) sum += num;
int left = sum/8;
// 明确上限:数组的最大值,最大值肯定满足
// 如果不知道怎么计算,就使用整数的最大值
int right = nums.back();
// 二分法:左闭右闭
while(left <= right){
int mid = left + (right - left)/2;//防止溢出
if(check(nums, mid)){
right = mid - 1;
}else{
left = mid + 1;
}
}
cout << left << endl;
return 0;
}