P7713 「EZEC-10」打分 题解
题目传送门
可能更好的阅读体验
思路
很简单的贪心,我们可以把打分的情况分为三种讨论。
显然,如果要使得答案尽量大,就尽量把除最小得分以外的分数都加成最大的分数。我们可以假设要把除最小值、最大值以外的分数都变成最大分需要加
1.
2.
3.
代码
2.1:处理前的准备
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);//排序后,a[1]是最小分数,a[n]是最大分数
for(int i=2;i<=n-1;i++){
sum+=(a[n]-a[i]);//求出要把所有除了最大和最小分数的分数变成最大分数需要加多少分,即要加多少次
cnt+=a[i];//求出除最大分数和最小分数的总和
}
我使用了较慢的排序函数来排除最小分数和最大分数,当然可以使用更快的
2.2:第一种情况的处理
if(sum==m){
cout<<a[n]*(n-2)<<endl;
return 0;
}
当
2.3:第二种情况的处理
else if(sum>m){
cout<<cnt+m<<endl;
return 0;
}
当
2.4:第三种情况的处理
else{
for(int i=2;i<=n-1;i++){
a[i]=a[n];//先把所有除了最小最大分数以外的分数都变成最大分数
}
m-=sum;//算出m还剩下多少可以用
for(int i=2;i<=n;i++){
a[i]+=m/(n-1);//先把m平摊分给除了最小分数以外的分数
}
for(int i=2;i<=1+m%(n-1);i++){
a[i]++;//如果还有剩的,就把区间[2,1+m%(n-1)]中的a[i]都加一分。
}
sort(a+1,a+n+1);//再次排序
for(int i=2;i<=n-1;i++){
ans+=a[i];//再次求和
}
cout<<ans<<endl;
return 0;//好习惯
}
当
AC Code
AC记录