题目链接:https://ac.nowcoder.com/acm/contest/6220/C
Description
牛牛有n件带水的衣服,干燥衣服有两种方式。
一、是用烘干机,可以每分钟烤干衣服的k滴水。
二、是自然烘干,每分钟衣服会自然烘干1滴水。
烘干机比较小,每次只能放进一件衣服。
注意,使用烘干机的时候,其他衣服仍然可以保持自然烘干状态,现在牛牛想知道最少要多少时间可以把衣服全烘干。
Sample Input
3,[2,3,9],5
Sample Output
3
Interpretation
前两分钟对第三件衣服进行烘干机烘干,使得衣服的水份分别为0,1,0,所以最快三分钟可以烘干。
Hint
第一个参数n(1 ≤ n ≤ 10^5),代表一共有多少件衣服。
第二个参数为n个数(1 ≤ an ≤ 10^9)组成的数组,代表n件衣服分别有多少水滴水。
第三个参数k(1 ≤ k ≤ 10^9),代表烘干机每分钟能烘干k滴水。
程序应返回:一个整数,代表使n件衣服全部干燥所需要的最少的时间。
Solution
经典二分题目。直接二分答案。
这种问题直接去求答案可能是比较麻烦的,但我们如果假设已经知道了答案,然后去验证这个答案的正确性往往是比较简单的。首先我们需要找出答案二分的范围,显然,最小时间L不会小于0,最大时间不会超过a[i]的最大值。你可以求a[i]的最大值,或者直接将a[i]取值范围内的最大值赋给R也可以。
取mid = (L + R) / 2,然后判断一下mid符不符合条件,符合的话,砍掉mid后面的,记录一下ans=mid,否则砍掉mid前面的。直到L>R,二分结束,ans就是最小时间。
Code
class Solution {
public:
/**
* 计算最少要多少时间可以把所有的衣服全烘干
* @param n int整型 n件衣服
* @param a int整型vector n件衣服所含水量数组
* @param k int整型 烘干机1分钟可以烘干的水量
* @return int整型
*/
bool check(int mid,int n,vector<int>& a, int k) {
long long sum = 0;
for (int i = 0; i < n; i++) {
if (a[i]>mid) sum += ceil((a[i] - mid)*1.0/( k - 1));
}
return sum <= mid;
}
int solve(int n, vector<int>& a, int k) {
// write code here
sort(a.begin(),a.end());
if (k == 1) return a[n-1];
int L = 0, R = a[n-1];
int ans = 0;
while (R >= L) {
int mid = (L + R) / 2;
if (check(mid,n,a,k)) R = mid - 1, ans = mid;
else L = mid+1;
}
return ans;
}
};