CF Round #510 (Div. 2)

前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了。。最后才\(A\)\(3\)题,幸好\(Rating\)没掉。

A. Benches

Description

\(n\)个位置,给出每个位置上原本有\(a[i]\)个人。现有\(m\)个人,把他们安排到这\(n\)个位置上,设安排完后位置上人数最多的位置有\(k\)个人,求最大的\(k\)和最小的\(k\)

Solution

官方正解复杂度为\(O(mn)\)
而我机房里有大佬写了二分答案的做法(传送门
这里给出我的\(O(n)\)做法。
最大值显然就是\(n\)个位置上原有的最多的人数加上\(m\)
对于最小值,其实就是去填\(n\)个位置,使得每个位置的人数尽量平均,设原有最多人数为\(maxn\),则一共可以填\(\sum\limits_{i=1}^n maxn-a[i]\)个人。
若填完后没有剩余,则答案就是\(maxn\);若有剩余,则将剩余的人平均分配到\(n\)个位置即可。

#include<cstdio>
#include<cmath>
using namespace std;
const int N = 110;
int a[N];
inline int re()
{
    int x = 0;
    char c = getchar();
    bool p = 0;
    for (; c < '0' || c > '9'; c = getchar())
        p |= c == '-';
    for (; c >= '0' && c <= '9'; c = getchar())
        x = x * 10 + c - '0';
    return p ? -x : x;
}
inline int maxn(int x, int y)
{
    return x > y ? x : y;
}
int main()
{
    int i, n, m, ma = 0, s = 0;
    n = re();
    m = re();
    for (i = 1; i <= n; i++)
    {
        a[i] = re();
        ma = maxn(ma, a[i]);
    }
    for (i = 1; i <= n; i++)
        s += ma - a[i];
    if (s >= m)
        printf("%d %d", ma, ma + m);
    else
        printf("%d %d", ma + (int)ceil(1.0 * (m - s) / n), ma + m);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Iowa-Battleship/p/9664937.html
今日推荐