http://codeforces.com/contest/581/problem/C
给你n个技能,和一个k
n个数代表技能当前level (最高level是100)
让你求the sum of the values of for all i from 1 to n.
因为是除十取整,所以我们只要尽可能加够整十,例如18和12对答案的贡献分别都是1,但是20和10对答案的贡献分别是2和1
__int64 get_need(__int64 x) { if (x==0) return 0; if (x%10==0) return 0; __int64 tmp=x/10; return (tmp+1)*10-x; }
直接预处理一遍,把每个数 离最接近的整十数的差距 算处理存到need[i]
for (i=1;i<=n;i++) { sum+=nd[i].need; }
然后遍历统计 need[i]值
得到使所有数升级 到下一个有效level需要的 points
如果 k 大于sum,我们先让所有的数升级到整十,同时k-=sum
此时统计一下 当前得到的ans
然后对k判断,只需要对把答案加上 ans/k就可以了,要注意 由于最高level只有100,所以最大的ans不可能超过 10*n
其次,如果k<sum
只需要对need数组排序,把k尽量分配给need值小的数。
最后直接求和即。。。。。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <map> #include <set> #include <vector> using namespace std; __int64 min(__int64 a,__int64 b) { return a<b?a:b; } __int64 max(__int64 a,__int64 b) { return a>b?a:b; } struct node { __int64 num; __int64 need; }; node nd[100005]; __int64 get_need(__int64 x) { if (x==0) return 0; if (x%10==0) return 0; __int64 tmp=x/10; return (tmp+1)*10-x; } __int64 cmp(node a,node b) { return a.need<b.need; } __int64 tm[100005]; int main() { __int64 a,b; __int64 k; __int64 n; scanf("%I64d%I64d",&n,&k); __int64 i; for (i=1;i<=n;i++) { scanf("%I64d",&tm[i]); } for (i=1;i<=n;i++) { nd[i].need=get_need(tm[i]); nd[i].num=i; } sort(nd+1,nd+1+n,cmp); __int64 sum=0; __int64 ans=0; for (i=1;i<=n;i++) { sum+=nd[i].need; } if (k>=sum) { for (i=1;i<=n;i++) { __int64 tmp=tm[i]/10; if (tmp*10==tm[i]) ans+=tmp; else { ans+=tmp+1; } } k-=sum; ans+=min(k/10,n*10-ans); } else { for (i=1;i<=n;i++) { if (k>=nd[i].need) { k-=nd[i].need; tm[nd[i].num]+=nd[i].need; } else break; if (k==0) break; } for (i=1;i<=n;i++) { ans+=(tm[i]/10); } } printf("%I64d\n",ans); return 0; }