当前位置: 首页 > article >正文

中位数定理:小试牛刀> _ <2025牛客寒假1

给定数轴上的n个点,找出一个到它们的距离之和尽量小的点(即使我们可以选择不是这些点里的点,我们还是选择中位数的那个点最优)
结论:这些点的中位数就是目标点。可以自己枚举推导(很好想)
(对于 点的数量为奇数,是排序之后最中间的数 ,对于点的数量为偶数的情况下,中间两个点 都可以,他俩的答案是相同的,可以简单的画图证明,或者直接抽象一点的想:假设这两个点分别为A B他们之间的距离为d,A相对于B 来说,左侧的点都减少d ,右侧的点都增加d .又因为A左侧的点的个数等于B 右侧的点,所以A B 的值相同)

板子题

void solve()
{
    int n;cin>>n;
    vector<int>a(n);
    for (int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a.begin(),a.end());
    int ans=0;
    for (int i =0;i<n;i++)
    {
        ans+=abs(a[i]-a[n>>1]);
    }
    cout<<ans<<"\n";
}

添加链接描述
在这里插入图片描述
根据上边的引入,可以想到 将数组从中间分成两个子数组。
在考虑一种特殊的情况,就是我两个子数组的中位数相同,这样就不符合题目的要求。
这个时候,两个子数组的中位数肯定有一个要变一下。
有两种可能 左边的中位数-1 / 右边的中位数加1
(为啥左边的中位数不能+1 呢,因为加1 减1 对于数值是原本的中位数的数字 距离是相同的,但是我前边的数大概率有小于我原本中位数的数值,所以我中位数-1 ,距离小的数更进了)

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
#define int long long

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a.begin(), a.end());
    if (n == 2)
    {
        if (a[0] != a[1])
        {
            cout << "0\n";
        }
        else
            cout << '1' << "\n";
        return;
    }
    int len = n;
    len /= 2;
    int pos1 = len / 2;
    int pos2 = len + len / 2;

    int ans=0;
    if (a[pos1] != a[pos2])
    {
        //[0 len-1]
        for (int i=0;i<len;i++)
        {
            ans+=abs(a[i]-a[pos1]);
        }
        for (int i=len;i<n;i++)
        {
            ans+=abs(a[i]-a[pos2]);
        }

    }
    else
    {
        int tar=a[pos2]+1;
        for (int i=0;i<len;i++)
        {
            ans+=abs(a[i]-a[pos1]);
        }
        for(int i=len;i<n;i++)
        {
            ans+=abs(a[i]-tar);
        }
        int t=0;
        tar=a[pos1]-1;
        for (int i=0;i<len;i++)
        {
            t+=abs(a[i]-tar);
        }
        for (int i=len;i<n;i++)
        {
            t+=abs(a[i]-a[pos2]);
        }
        ans=min(ans,t);
    }
    cout<<ans<<'\n';
}
signed main()
{
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}


http://www.kler.cn/a/534261.html

相关文章:

  • Qt展厅播放器/多媒体播放器/中控播放器/帧同步播放器/硬解播放器/监控播放器
  • 大数据学习之Spark分布式计算框架RDD、内核进阶
  • 构建一个翻译助手Agent:提升翻译效率的实践
  • 信标链的基本概念
  • 【电脑系统】电脑突然(蓝屏)卡死发出刺耳声音
  • DeepSeek 阐述 2025年前端发展趋势
  • 工作流项目BPMN.JS_Question梳理
  • 防孤岛保护装置在分布式光伏并网中的应用
  • 【深度学习框架】MXNet(Apache MXNet)
  • 体验 DeepSeek 多模态大模型 Janus-Pro-7B
  • 浙江安吉成新照明电器有限公司分布式光伏发电项目--安科瑞Acrel-1000DP分布式光伏监控系统
  • ES6 字符串、数值、数组扩展使用总结
  • 30.日常算法
  • 【Elasticsearch】 日期直方图聚合(`date_histogram`)
  • IC卡读卡器web插件YOWOCloudRFIDReader.js
  • 基于ArcGIS的SWAT模型+CENTURY模型模拟流域生态系统水-碳-氮耦合过程研究
  • C# Monitor类 使用详解
  • K8S学习笔记-------2.极简易懂的入门示例
  • OSCP - Other Machines - sar2HTML
  • JeecgBoot 对接本地化的大模型 DeepSeek-R1
  • 64.进度条 C#例子 WPF例子
  • vue3中的ref相关的api及用法
  • 离散时间傅里叶变换(DTFT)公式详解:周期性与连续性剖析
  • matlab实现了一个多视角受限核机算法,结合了多个视角的数据进行二分类任务
  • 2.5学习总结
  • Unity渲染管线