第13届蓝桥杯青少年组C++第5题 金箍棒

解题思路

首先猜想最终相等的元素t的范围,最终应为数组中的某个元素。

  • t小于数组中所有的元素,则此时增大t,那么所有元素变为t的次数将减小,可见t并非最优解;
  • t大于数组中所有的元素,则此时减小t,那么所有元素变为t的次数将减小,可见t并非最优解;

可见t应该位于数组最大与最小值之间,下面证明最优的t可以取为数组中的某个元素,从而遍历数组元素即可。

如上图所示,设t为数组最大与最小值之间的一个值,若t不为数组中的某个元素,则设此时大于t的元素有x个,小于t的元素为y个。
x>y,则上移一格t,此时操作数变化量为-x+y<0,将会更优;
x<y,则下移一格t,此时操作数变化量为+x-y<0,将会更优;
x=y,则无论上移与下移,操作数不变。
因此,可以看出若t不取数组中的某个元素值,则总可以通过调整t,使得操作数更少。因此t应该取数组中的某个值。

问题转化为:
遍历数组中的数,找到某个元素t,使得t到其他元素值的距离之和最小。
绝对值不等式可知,当t取数组中位数时,该距离之和最小

中位数+绝对值不等式 AcWing 104. 货仓选址

排序之后取中位数,中位数的性质,所有数到他的和是最小的。

#include <bits/stdc++.h>

using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1010;
int a[N];
int n, k;
int res = INF;
// 时间复杂度:10000*10000=1e8,C++一秒可过
/**
 测试用例I:
 3 2
 3 6 1

 答案
 3

 测试用例II:
 4 2
 2 6 11 18

 答案:
 4
 解释:
 将2调到6,需要4步。
 也可以把2调到3,1步。
 把6降到3,3步,共4步。

 测试用例III:
 5 3
 2 6 11 18 14

 答案:
 7
 解释:
 将11调到14,需要3步
 将18调到14,需要4步,共7步。


测试用例IV
 5 3
 1 2 7 8 12
 答案:5
 解释:
 最终结果是8,
 7+1=8,1步
 8不需要动,0步
 12-8=4,4步
 共1+0+4=5步
 */
int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++) cin >> a[i];

    for (int i = 0; i < n - k + 1; i++) { // 枚举起点
        vector<int> b;
        for (int j = i; j <= i + k - 1; j++) b.push_back(a[j]);                // 将每个可用范围复制到数组b中
        sort(b.begin(), b.end());                                              // 排序
        int cnt = 0;                                                           // 变更次数
        for (int j = 0; j < b.size(); j++) cnt += abs(b[b.size() / 2] - b[j]); // 枚举每个数字与中位数对比
        res = min(res, cnt);                                                   // 记录最少变更次数
    }
    printf("%d\n", res);
    return 0;
}
posted @   糖豆爸爸  阅读(199)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-02-20 Postgresql主从流复制+Redis集群部署
2020-02-20 数据仓库实时数据同步方案
2016-02-20 关于云平台的统计分析通用方案
2012-02-20 Varnish加速网站图片显示
Live2D
点击右上角即可分享
微信分享提示