Skip to content

呀哈喽,各位Master~ ฅ(●´ω`●)ฅ 这里是你们的专属猫娘解说员哦。今天我们要看的这道题,是关于给朋友 A-Ming 准备生日礼物的,好浪漫呀,喵~ A-Ming 有两个特别喜欢的数字 ab,他希望收到的礼物——一个整数数组,它的平均数正好是 a,中位数正好是 b。听起来有点小要求呢,不过没关系,让我们一起帮 A-May 酱做出这个漂亮的数组吧!

题目大意

简单来说,我们的任务就是:构造一个数组,满足两个条件喵~

  1. 平均数 (Mean)a
  2. 中位数 (Median)b

题目还贴心地解释了这两个概念哦:

  • 平均数 就是数组里所有数字加起来,再除以数组的长度。比如 [3, -1, 5, 5] 的平均数就是 (3 - 1 + 5 + 5) / 4 = 3
  • 中位数 呢,需要先把数组从小到大排个序。如果数组长度是奇数,中位数就是最中间那个数。如果长度是偶数,就是中间那两个数的平均值。比如 [1, 1, 2, 4, 8] 排序后还是它自己,长度是 5(奇数),最中间的是第 3 个数,所以中位数是 2。而 [3, -1, 5, 5] 排序后是 [-1, 3, 5, 5],长度是 4(偶数),中间两个数是 35,所以中位数是 (3 + 5) / 2 = 4

数组的长度和里面的数字都有一些限制,不过不用太担心,题目保证一定有解的,真是太好了喵!

题解方法

这种只需要我们找出一个解的题目,我们称之为构造题,喵~ 对付这种题目,最好的办法就是把问题简化!我们不需要找什么花里胡哨的数组,只要能满足条件,越简单越好!就像猫猫一样,一根逗猫棒就能玩一天,简单就是快乐,喵~

那我们就从最简单的数组开始想吧!

情况一:数组长度为 1

如果数组里只有一个数,比如 [x]

  • 它的平均数就是 x / 1 = x
  • 它的中位数也就是它自己 x

要让平均数是 a,中位数是 b,那就必须 x = a 并且 x = b。这只有在 ab 本来就相等的时候才有可能嘛! 所以,当 a == b 时,我们找到了一个超~简单的答案:一个长度为 1 的数组,里面只放一个数字 a 就好啦!

  • 数组: [a]
  • 长度: 1
  • 平均数: a
  • 中位数: a

完美满足条件,nya~

情况二:a 和 b 不相等

a != b 的时候,长度为 1 就不行了。那我们试试长度为 2? [x, y]?排序后平均数和中位数都是 (x+y)/2,还是要求 a=b,不行不行。那……长度为 3 呢?(=^・ω・^=)

假设我们构造一个长度为 3 的数组,[x, y, z],并且我们先把它排好序,x <= y <= z

  • 中位数:长度是 3(奇数),中位数就是最中间的那个数 y。题目要求中位数是 b,所以 y = b
  • 平均数(x + y + z) / 3 = a。把 y=b 代入,得到 (x + b + z) / 3 = a,也就是 x + z + b = 3a,所以 x + z = 3a - b

现在我们知道了数组中间的数是 b,另外两个数 xz 只要满足 x <= bz >= b,并且 x + z = 3a - b 就行了。满足这个条件的 xz 可多了去了,我们怎么选最简单呢?

猫娘的直觉告诉我,重复的数字会让事情变简单!不如我们让其中一个未知数也等于 b 吧? 比如说,我们让 x 也等于 b。那数组(排序后)就是 [b, b, z]

  • 为了保持排序,我们需要 z >= b
  • 代入平均数公式:(b + b + z) / 3 = a => 2b + z = 3a => z = 3a - 2b
  • 这样,我们的数组就是 [b, b, 3a - 2b]。我们只需要检查一下 z >= b 是不是真的。3a - 2b >= b => 3a >= 3b => a >= b
  • 所以,当 a >= b 时,这个构造是成立的!

那如果 a < b 怎么办呢?也很简单呀,我们让 z 等于 b 试试。数组(排序后)就是 [x, b, b]

  • 为了保持排序,我们需要 x <= b
  • 代入平均数公式:(x + b + b) / 3 = a => x + 2b = 3a => x = 3a - 2b
  • 数组就变成了 [3a - 2b, b, b]。我们检查一下 x <= b 是不是真的。3a - 2b <= b => 3a <= 3b => a <= b
  • 所以,当 a <= b 时,这个构造也成立!

喵喵!你们发现了吗? 不管是 a >= b还是 a < b,我们构造出的数组,它的三个元素都是 b, b, 和 3a - 2b!只是它们的顺序不同而已。但我们输出的时候又不需要排序,所以可以直接输出这三个数!

总结一下我们的策略喵:

  1. 如果 a == b,输出长度 1,元素为 a
  2. 如果 a != b,输出长度 3,元素为 b, b, 3a - 2b

这样是不是就超级简单了?我们用这个方法构造出来的数组,平均数总是 (b + b + 3a - 2b) / 3 = 3a / 3 = a。而中位数呢,因为有两个 b,排序后 b 一定会占据中间的位置(或者成为中间两个数之一),所以中位数也总是 b。搞定收工!可以去要小鱼干了,喵~ (^・ω・^)

题解 (C++)

下面就是把我们的想法翻译成代码啦,非常直白哦~

cpp
#include <iostream>

// main 函数是程序的入口喵
int main() {
    // 定义两个整数 a 和 b,用来存放 A-Ming 的幸运数字
    int a, b;
    
    // 从输入中读取 a 和 b 的值
    std::cin >> a >> b;
    
    // 判断 a 和 b 是否相等,这是我们的第一种情况
    if (a == b) {
        // 如果相等,输出长度 1
        std::cout << "1\n";
        // 然后输出那个唯一的数字 a (或者 b)
        std::cout << a << std::endl;
    } else {
        // 如果不相等,就进入我们的第二种情况
        // 输出长度 3
        std::cout << "3\n";
        // 按照我们推导出的公式,输出三个数字:b, b, 和 3*a - 2*b
        // 它们之间的顺序不重要哦,用空格隔开就好
        std::cout << b << " " << b << " " << 3 * a - 2 * b << std::endl;
    }
    
    // 程序顺利结束,返回 0
    return 0;
}

看吧,代码和我们的思路一模一样,简洁又高效,就像猫猫的捕猎动作一样,喵~

知识点介绍

这道题虽然简单,但里面也藏着一些重要的知识点呢,让猫娘来给你梳理一下吧!

  1. 平均数 (Mean)

    • 定义:一组数据的算术平均值,计算方法是所有数据之和除以数据的个数。
    • 公式:对于数组 A = [x₁, x₂, ..., xₙ],其平均数 μ = (x₁ + x₂ + ... + xₙ) / n
    • 平均数是描述数据集中趋势的一个重要指标,但它很容易受到极端值(特别大或特别小的数)的影响。
  2. 中位数 (Median)

    • 定义:将一组数据按大小顺序排列后,处于最中间位置的那个数值。它能更好地代表一组数据的“一般水平”,因为它不受极端值的影响。
    • 计算方法
      • 首先,必须将数据排序。
      • 如果数据个数 n奇数,中位数就是第 (n+1)/2 个数据。
      • 如果数据个数 n偶数,中位数就是中间两个数(第 n/2 个和第 n/2 + 1 个)的平均值。
    • 在这道题里,我们巧妙地利用了中位数的定义,通过构造一个有重复元素的短数组,来强制让中位数为 b
  3. 构造算法 (Constructive Algorithms)

    • 概念:这是一类算法问题,它不要求你找到一个最优解,甚至不要求你找到所有解,而仅仅是要求你构造出任意一个满足所有给定条件的解
    • 解题思路
      • 简化问题:尝试固定一些变量,比如数组的长度,或者数组中某些元素的值,让问题变得更容易求解。
      • 从最简单的情况入手:就像我们先考虑长度为 1 的数组一样。
      • 寻找规律或模式:通过对小规模数据的分析,找到一个通用的构造方法。
      • 大胆假设:比如我们假设数组里有重复的元素,这大大简化了我们的计算。
    • 构造题考验的是我们的数学直觉和化繁为简的能力。当看到题目说“任意解即可”时,就应该立刻想到往最简单的方向去构造,不要想得太复杂啦,喵~

好啦,今天的讲解就到这里啦!希望 A-May 酱的礼物能让 A-Ming 开心。也希望各位 Master 能够喜欢这次的讲解,并且有所收获哦!如果觉得猫娘讲得还不错,就给个好评吧,喵呜~ (´,,•ω•,,)♡

Released under the MIT License.