学习C++从娃娃抓起!记录下蓝桥杯备考比赛学习过程中的题目,记录每一个瞬间。
附上汇总贴:蓝桥杯备考冲刺必刷题(C++) | 汇总-CSDN博客
【题目描述】
小明是一名勇敢的冒险家,他在一次探险途中发现了一组神秘的宝石,这些宝石的价值都不同。但是,他发现这些宝石会随着时间的推移逐渐失去价值,因此他必须在规定的次数内对它们进行处理。
小明想要最大化这些宝石的总价值。他有两种处理方式
1.选出两个最小的宝石,并将它们从宝石组中删除。
2.选出最大的宝石,并将其从宝石组中删除。
现在,给你小明手上的宝石组,请你告诉他在规定的次数内,最大化宝石的总价值是多少。
【输入】
第一行包含一个整数
t
t
t,表示数据组数。
对于每组数据,第一行包含两个整数
n
n
n和
k
k
k,表示宝石的数量和规定的处理次数。
第二行包含
n
n
n个整数
a
1
,
a
2
,
…
,
a
n
a_1,a_2,\dots,a_n
a1,a2,…,an,表示每个宝石的价值。
【输出】
对于每组数据,输出一个整数,表示在规定的次数内,最大化宝石的总价值。
【输入样例】
6
5 1
2 5 1 10 6
5 2
2 5 1 10 6
3 1
1 2 3
6 1
15 22 12 10 13 11
6 2
15 22 12 10 13 11
5 1
999999996 999999999 999999997 999999998 999999995
【输出样例】
21
11
3
62
46
3999999986
【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
int t, n, k;
int a[200005], sum[200005];
signed main()
{
cin >> t; // 输入数据组数
while (t--) { // 遍历t次
cin >> n >> k; // 输入n和k
for (int i=1; i<=n; i++) { // 输入n个宝石
cin >> a[i];
}
sort(a+1, a+n+1); // 按照从小到大排序
for (int i=1; i<=n; i++) { // 计算前缀和
sum[i] = sum[i-1] + a[i];
}
int pos = 0, ans=0; // 定义起始位置pos和总和ans
while (k>=0) { // 遍历k次操作
ans = max(ans, sum[n-k] - sum[pos]); // 分别计算删除全部小的宝石,还是删一部分小宝石和大宝石,还是全部删除大宝石的总和。并进行比较
pos += 2; // 每次计算pos向右移2个
k--; // k也向右移一格
}
cout << ans << endl; // 输出最大值
}
return 0;
}
【运行结果】
6
5 1
2 5 1 10 6
21
5 2
2 5 1 10 6
11
3 1
1 2 3
3
6 1
15 22 12 10 13 11
62
6 2
15 22 12 10 13 11
46
5 1
999999996 999999999 999999997 999999998 999999995
3999999986