洛谷 1873题 砍树

这道题也是典型的二分查找问题.

思路:假设我们知道这个锯断高度是x,就像leetcode 2861题那样,check()就是判断这些树与锯断的差值加起来与m作比较的问题,这样的话就可以写出来了。

注意:在确定范围的时候一定要注意一些小细节,例如二分模板选哪个,left和right该如何取值的问题,这里,你可以取right为它的最大数据范围,也可以直接用数组中的最大值作为right,都可以。

#include
#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 10000010
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std; 
typedef long long LL;
LL arr[MAX];
LL lefts, rights;
int main() {
	LL n, m;
	cin >> n >> m;
	for (long long i = 0; i < n; i++)
		cin >> arr[i];
	LL res = 0;
	for (long long i = 0; i < n; i++)
		rights = max(arr[i], rights);
	while (lefts < rights) {
		LL mid = (lefts + rights+1) / 2;
		LL sum = 0;
		for (long long j = 0; j < n; j++) {
			if (mid < arr[j])
				sum += arr[j] - mid;
		}
		if (sum >= m)
		{
			lefts = mid;
		}
		else
			rights = mid - 1;
	}
	cout << lefts << endl;

	return 0;
}

你可能感兴趣的:(算法,c++)