经典二分题 - 牛牛晾衣服

题目链接: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;
    }
};

猜你喜欢

转载自blog.csdn.net/buibuilili/article/details/107510582