P1837 砍樹題解
阿新 • • 發佈:2021-07-22
模板1解法
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 10; int a[N]; int n; LL m; bool check(int x) { LL sum = 0; for (int i = n; i >= 1; i--) if (a[i] > x) sum += a[i] - x; return sum < m; } int main() { //輸入 cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; //排序 sort(a + 1, a + 1 + n); //模板2,找右邊界 int l = a[1], r = a[n]; while (l < r) { int mid = (l + r) >> 1; if (check(mid))r = mid; //向左! else l = mid + 1; //不行再向右! } cout << l - 1 << endl; //最終停止時,多加的那個1要減出去 return 0; }
模板2解法
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 10; int a[N]; int n; LL m; bool check(int x) { LL sum = 0; for (int i = n; i >= 1; i--) if (a[i] > x) sum += a[i] - x; return sum >= m; } int main() { //輸入 cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; //排序 sort(a + 1, a + 1 + n); //模板2,找右邊界 int l = a[1], r = a[n]; while (l < r) { int mid = (l + r + 1) >> 1;//砍樹的高度 if (check(mid)) l = mid; else r = mid - 1; } cout << l << endl; return 0; }