蓝桥杯入门赛

第28场 算法赛 第四题题解

表演队

在这里插入图片描述
idea: 前缀和+滑动窗口

#include <iostream>
#include <algorithm>
using namespace std;

// 定义数组来存储每个同学的表演能力值
const int MAXN = 100005;
int ability[MAXN];
// 定义前缀和数组,用于快速计算区间内表演能力值的总和
long long prefixSum[MAXN];

int main() {
    int totalStudents, selectedStudents;
    // 读取同学的总数 totalStudents 和需要挑选的同学数量 selectedStudents
    cin >> totalStudents >> selectedStudents;
    for (int i = 1; i <= totalStudents; i++) {
        cin >> ability[i];
    }

    // 对表演能力值数组进行排序,使得相近能力值的同学相邻
    sort(ability + 1, ability + 1 + totalStudents);

    // 初始化当前差异值和最小差异值
    long long currentDiff = 0;
    long long minDiff = 9e18; 

    // 开始遍历每个同学,同时构建前缀和数组并计算差异值
    for (int i = 1; i <= totalStudents; i++) {
        // 计算前缀和,prefixSum[i] 表示前 i 个同学表演能力值的总和
        prefixSum[i] = prefixSum[i - 1] + ability[i];

        if (i < selectedStudents) {
            // 当还未选够 selectedStudents 个同学时
            // 计算当前同学与前面已选同学表演能力值的差异并累加到 currentDiff
            currentDiff += (long long)ability[i] * (i - 1) - prefixSum[i - 1];
        } else if (i == selectedStudents) {
            // 当刚好选够 selectedStudents 个同学时
            // 同样计算当前同学与前面已选同学表演能力值的差异并累加到 currentDiff
            currentDiff += (long long)ability[i] * (i - 1) - prefixSum[i - 1];
            // 更新最小差异值
            minDiff = min(minDiff, currentDiff);
        } else {
            // 当已经选了超过 selectedStudents 个同学时,使用滑动窗口的思想
            // 计算新加入的同学与当前窗口内其他同学的差异
            currentDiff += (long long)ability[i] * (selectedStudents - 1) - (prefixSum[i - 1] - prefixSum[i - selectedStudents]);
            // 减去滑出窗口的同学对差异值的影响
            currentDiff -= prefixSum[i - 1] - prefixSum[i - selectedStudents] - (long long)ability[i - selectedStudents] * (selectedStudents - 1);
            // 更新最小差异值
            minDiff = min(minDiff, currentDiff);
        }
    }

    // 输出最小差异值
    cout << minDiff << '\n';

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值