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} ight floor}$堆,每一堆$k$个,那么这种颜色就会有${{a_i ~~ mod ~~k}}$个球多出来,所以当且仅当 ${{left lfloor frac{a_i}{k}  ight  floorgeq (a_i ~~ mod ~~k)}}$ 才合法,然后对于剩下的$n-1$种颜色的判断一下这个$k$值是否合法,统计一下总数,因为这样的$k$对于最小的${a_i}$只有根号种取值,所以复杂度为${O(n* sqrt 1e9)}$

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

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 100100
10 #define llg int
11 #define LL long long
12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
13 llg n,m,c[maxn],tail,a[maxn];
14 LL ans=(LL)1e16;
15 
16 inline int getint()
17 {
18        int w=0,q=0; char c=getchar();
19        while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
20        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
21 }
22 
23 int main()
24 {
25     yyj("ball");
26     cin>>n;
27     for (llg i=1;i<=n;i++) a[i]=getint();
28     sort(a+1,a+n+1);
29     llg up=sqrt(a[1]+0.5);
30     for (llg i=1;i<=up;i++) if (a[1]/i>=a[1]%i) c[++tail]=i;
31     for (llg i=1;i<=up;i++)
32     {
33         llg k=a[1]/i;
34         if (a[1]/k>=a[1]%k) c[++tail]=k;
35         k--; if (!k) continue;        
36         if (a[1]/k>=a[1]%k) c[++tail]=k;
37     }
38     for (llg i=1;i<=tail;i++)
39     {
40         llg k=c[i];
41         bool pd=1;
42         for (llg j=1;j<=n;j++) if (a[j]/k<a[j]%k) pd=false;
43         if (pd) 
44         {
45             LL sum=0;
46             for (llg j=1;j<=n;j++) sum+=a[j]/(k+1)+(a[j]%(k+1)!=0);
47             ans=min(ans,sum);
48         }
49     }
50     cout<<ans;
51     return 0;
52 }
原文地址:https://www.cnblogs.com/Dragon-Light/p/6651862.html