1. 程式人生 > 其它 >P1837 砍樹題解

P1837 砍樹題解

題目傳送門

模板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;
}