前言:没想到那么快就打了第二场,题目难度比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;
}