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;
}