Codeforces 792 E. Colored Balls

时间:2023-03-09 21:48:35
Codeforces 792 E. Colored Balls

题目链接:http://codeforces.com/contest/792/problem/E


  假设含球较少的那些堆有 $mi$ 个球,较多的那些堆有$ma$个球,$ma=mi+1$,考虑对于最小的$a_i$枚举值 $mi$ ,表示我要将这堆求分成${\left \lfloor \frac{a_i}{k} \right \rfloor}$堆,每一堆$k$个,那么这种颜色就会有${{a_i ~~ mod ~~k}}$个球多出来,所以当且仅当 ${{\left \lfloor \frac{a_i}{k} \right \rfloor\geq (a_i ~~ mod ~~k)}}$ 才合法,然后对于剩下的$n-1$种颜色的判断一下这个$k$值是否合法,统计一下总数,因为这样的$k$对于最小的${a_i}$只有根号种取值,所以复杂度为${O(n* \sqrt 1e9)}$

  注意一下这种trick:答案爆$int$,枚举合法的$k$的时候要再判断一下${ai/k+1}$(样例),最后在算的时候是优先一堆放$ma$个的。

  

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 100100
#define llg int
#define LL long long
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,c[maxn],tail,a[maxn];
LL ans=(LL)1e16; inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} int main()
{
yyj("ball");
cin>>n;
for (llg i=;i<=n;i++) a[i]=getint();
sort(a+,a+n+);
llg up=sqrt(a[]+0.5);
for (llg i=;i<=up;i++) if (a[]/i>=a[]%i) c[++tail]=i;
for (llg i=;i<=up;i++)
{
llg k=a[]/i;
if (a[]/k>=a[]%k) c[++tail]=k;
k--; if (!k) continue;
if (a[]/k>=a[]%k) c[++tail]=k;
}
for (llg i=;i<=tail;i++)
{
llg k=c[i];
bool pd=;
for (llg j=;j<=n;j++) if (a[j]/k<a[j]%k) pd=false;
if (pd)
{
LL sum=;
for (llg j=;j<=n;j++) sum+=a[j]/(k+)+(a[j]%(k+)!=);
ans=min(ans,sum);
}
}
cout<<ans;
return ;
}