图片说明 如果跳转失败点击这里

图片说明

解题思路

对于每个人只能吃到的鸽子肉只能来自于一只鸽子但是一只鸽子可以给分割被很多人吃。那么我们假设mid可以满足当前分配,自然而然地就知道想要这个答案更大一点的,那么如果这个mid不够给人分配,那么答案一定比mid更小,这样就满足了二分的性质。这里还要特判0因为mid做了除数,我写的就用了个累加,因为我写的二分是[l,r]的写法,不能直接吧0写进去,也可以用(l,r]的写法,把l输出,如果一次l都没有更新,那初值0输出。

二分在这个博客写了一下

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;

inline ll read() {
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}

const int N = 1e5 + 7;
int n, m;
ll a[N];

bool check(ll x) {
    ll cnt = 0;
    for (int i = 1; i <= n; ++i) {
        if (a[i] < x)    break;
        cnt += a[i] / x;
        if(cnt>=m)    return true;
    }
    return false;
}

int main() {
    n = read(), m = read();
    ll sum=0;
    for (int i = 1; i <= n; ++i)    a[i] = read(),sum+=a[i];
    if(sum<m){
        puts("0");
        return 0;
    }
    sort(a + 1, a + 1 + n, greater<ll>()); //从大到小排序
    ll l = 1, r = 1e9, mid, ans;
    while (l <= r) {
        mid = l + r >> 1;
        if (check(mid))    ans = mid, l = mid + 1;
        else    r = mid - 1;
    }
    printf("%lld\n", ans);
    return 0;
}