蓝桥杯省赛无忧 编程16 最大的卡牌价值

蓝桥杯省赛无忧 编程16 最大的卡牌价值_第1张图片

蓝桥杯省赛无忧 编程16 最大的卡牌价值_第2张图片
蓝桥杯省赛无忧 编程16 最大的卡牌价值_第3张图片

#include 
#include 
#include 
using namespace std;
int main() {
    int n, k;
    cin >> n >> k;
    vector<int> a(n), b(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> b[i];
    }
    long long totalValue = 0;
    vector<int> diffs;
    // 计算翻转每张卡牌后的潜在增益
    for (int i = 0; i < n; ++i) {
        totalValue += a[i];  // 初始总价值为所有正面的值
        diffs.push_back(b[i] - a[i]);
    }
    // 对增益从大到小排序
    sort(diffs.begin(), diffs.end(), greater<int>());
    // 在允许的操作次数内选择增益最大的翻转
    for (int i = 0; i < k && i < n; ++i) {
        if (diffs[i] > 0) {
            totalValue += diffs[i];
        }
    }
    cout << totalValue << endl; // 输出最大的卡牌价值和
    return 0;
}

代码分析:

  1. 初始化变量:

    • n :卡牌的数量。
    • k :允许翻转的次数。
    • a :存储每张卡牌正面的值的数组。
    • b :存储每张卡牌背面的值的数组。
    • totalValue :用于累积所有卡牌正面的总值。
    • diffs :用于存储每张卡牌翻转带来的价值差(即背面的值减去正面的值)的数组。
  2. 读取数据:

    • 使用cin读取用户输入的卡牌数量n和操作次数k
    • 循环读取每张卡牌正面和背面的值,并存储在数组ab中。
  3. 计算增益并求和:

    • 通过循环,将每张卡牌正面的值累加到totalValue变量中。
    • 同时计算每张卡牌的正、反面价值差,并将这个差值添加到diffs数组中。
  4. 排序:

    • 使用sort函数和greater()比较器对diffs数组进行降序排序。这会将最大的增益(最大的价值差)放在数组的开始位置。
  5. 选择性翻转卡牌:

    • 通过一个新的循环,遍历diffs数组中的前k个元素,或者直到数组的末尾(如果k > n)。
    • 在每次循环中,检查当前的增益是否为正,如果是,则将它加到totalValue中。加入正数增益确保操作后的总价值是增加的,而不是减少。
  6. 输出结果:

    • 使用cout输出最终的totalValue,即所有选定翻转操作后卡牌正面的最大总值。

代码的关键点在于:首先我们计算了所有可能的翻转增益,然后对这些增益进行排序,以确保我们首先考虑那些最有可能提高总价值的翻转。然后,我们只翻转那些确保能提高总价值的卡牌,直到达到我们的操作限制k。这种策略使我们能够最大化卡牌正面显示的总数值。

你可能感兴趣的:(蓝桥杯省赛无忧,蓝桥杯,算法,c++)