题解:ABC321B - Cutoff
·题目
链接:Atcoder。
链接:洛谷。
·难度
算法难度:C。
思维难度:C。
调码难度:B。
综合评价:见洛谷链接。
·算法
分情况讨论。
·思路
首先,如果目前的所有考试中分数最低的n-2场考试的分数加起来都能够满足要求,就直接输出0(即让第n次考试充当最低分),否则就把目前为止所有考试除了最低分和最高分之外都加起来,计算和与目标分数的差,如果该差小于等于目前最高分答案就是该差(让第n次考试充当中间值,即既不是最低也不是最高),否则就算你打的分再高,也只能作为最高分被忽略,所以只能输出-1。
·代价
O(n*log(n)),每个判断都需要遍历一边每次考试的分数,但是由于我投懒,连求最大最小值都想排一下序。
·细节
取最高分、最低分,用排序再合适不过。
·代码
#include<bits/stdc++.h>
#define N 110
using namespace std;
int a[N]={},n=0,x=0;
int calc();
//求出目前考试分数掐头去尾剩余的总和与目标分数的差,差大于目前最大值返回-1(因为会被作为最大值忽略),否则返回差值
bool check();
//判断“目前为止最小的n-2次考试的分数总和也够用”是否成立
int main(){
scanf("%d%d",&n,&x);
for(int i=1;i<n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+n);
//输入、排序
if(check()==true){
printf("%d\n",0);
//如果目前为止最小的n-2次考试的分数总和也够用最后一次考试交白卷都行
}else{
printf("%d\n",calc());
//否则输出calc的值
}
return 0;
}
int calc(){
int sum=0;
for(int i=2;i<n-1;i++){
sum+=a[i];
}
//求和(掐头去尾)
if(x-sum<=a[n-1]){
//小于目前最大值可以返回
return x-sum;
}
//否则返回-1
return -1;
}
bool check(){
int sum=0;
for(int i=1;i<n-1;i++){
sum+=a[i];
}
//求和(去尾)
if(sum>=x){
//够用就返回true
return true;
}
//否则返回false
return false;
}
·注意
输出0之后不要忘了退出程序。