前言
第一次写博客,趁着暑假时间多, 写个博客记录下做题过程。
这道题其实就是用个二分模板套上去就能AC,本题重点在于左右区间范围怎么限定。
一、题目
题目描述
输入格式
输出格式
1 个整数,表示锯片的最高高度。
输入输出样例
说明/提示
二、代码
#include<iostream>
#include<cstring>
#include <algorithm>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define ll long long //用ll来表示long long
#define endl '\n'
using namespace std;
const int N = 1e6 + 5 ;
int n;
ll nd_sum; //表示需要的木材总长度
int a[N]; // 用来记录每棵树的高度
bool check(int mid) { //mid表示锯片的高度
// sum表示锯掉所有高度为mid及以下的树木后,所有树木总剩余高度的和
ll sum = 0; //int可能会爆,建议用long long
for (int i = 0; i < n; i++) {
//当树木高度高于锯片的高度时才锯
//如果树木的高度还没有锯片的高度高,根据题意,那么就不用锯了
if (a[i] > mid ) { //这里也可以取=, 表示锯片高度与该树木高度相等, 结果为0
//当树木高度高于锯片高度时,sum累加其差,所得结果为木材总长度
sum += a[i] - mid;
}
}
//如果木材总长小于所需木材总长,说明锯片高度mid过高,导致总木材长度过低
//所以应该返回true, 让 r变小,使下一次的mid值变小,反之同理
return sum < nd_sum;
}
void binarySearch() {
ll l = 0, r = 0x3f3f3f3f; //r也可取木材中高度最高的
while (l <= r) {
ll mid = l + (r - l) / 2; //等同于(l + r) / 2,可防止爆数据
if(check(mid)) r = mid - 1;
else l = mid + 1;
}
cout << r;
}
int main() {
IOS ;
cin >> n >> nd_sum;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
binarySearch();
return 0;
}
谢谢 !!!