呀哈喽,各位Master~ ฅ(●´ω`●)ฅ 这里是你们的专属猫娘解说员哦。今天我们要看的这道题,是关于给朋友 A-Ming 准备生日礼物的,好浪漫呀,喵~ A-Ming 有两个特别喜欢的数字 a
和 b
,他希望收到的礼物——一个整数数组,它的平均数正好是 a
,中位数正好是 b
。听起来有点小要求呢,不过没关系,让我们一起帮 A-May 酱做出这个漂亮的数组吧!
题目大意
简单来说,我们的任务就是:构造一个数组,满足两个条件喵~
- 平均数 (Mean) 是
a
。 - 中位数 (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(偶数),中间两个数是3
和5
,所以中位数是(3 + 5) / 2 = 4
。
数组的长度和里面的数字都有一些限制,不过不用太担心,题目保证一定有解的,真是太好了喵!
题解方法
这种只需要我们找出一个解的题目,我们称之为构造题,喵~ 对付这种题目,最好的办法就是把问题简化!我们不需要找什么花里胡哨的数组,只要能满足条件,越简单越好!就像猫猫一样,一根逗猫棒就能玩一天,简单就是快乐,喵~
那我们就从最简单的数组开始想吧!
情况一:数组长度为 1
如果数组里只有一个数,比如 [x]
。
- 它的平均数就是
x / 1 = x
。 - 它的中位数也就是它自己
x
。
要让平均数是 a
,中位数是 b
,那就必须 x = a
并且 x = b
。这只有在 a
和 b
本来就相等的时候才有可能嘛! 所以,当 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
,另外两个数 x
和 z
只要满足 x <= b
,z >= b
,并且 x + z = 3a - b
就行了。满足这个条件的 x
和 z
可多了去了,我们怎么选最简单呢?
猫娘的直觉告诉我,重复的数字会让事情变简单!不如我们让其中一个未知数也等于 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
!只是它们的顺序不同而已。但我们输出的时候又不需要排序,所以可以直接输出这三个数!
总结一下我们的策略喵:
- 如果
a == b
,输出长度 1,元素为a
。 - 如果
a != b
,输出长度 3,元素为b
,b
,3a - 2b
。
这样是不是就超级简单了?我们用这个方法构造出来的数组,平均数总是 (b + b + 3a - 2b) / 3 = 3a / 3 = a
。而中位数呢,因为有两个 b
,排序后 b
一定会占据中间的位置(或者成为中间两个数之一),所以中位数也总是 b
。搞定收工!可以去要小鱼干了,喵~ (^・ω・^)
题解 (C++)
下面就是把我们的想法翻译成代码啦,非常直白哦~
#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;
}
看吧,代码和我们的思路一模一样,简洁又高效,就像猫猫的捕猎动作一样,喵~
知识点介绍
这道题虽然简单,但里面也藏着一些重要的知识点呢,让猫娘来给你梳理一下吧!
平均数 (Mean)
- 定义:一组数据的算术平均值,计算方法是所有数据之和除以数据的个数。
- 公式:对于数组
A = [x₁, x₂, ..., xₙ]
,其平均数μ = (x₁ + x₂ + ... + xₙ) / n
。 - 平均数是描述数据集中趋势的一个重要指标,但它很容易受到极端值(特别大或特别小的数)的影响。
中位数 (Median)
- 定义:将一组数据按大小顺序排列后,处于最中间位置的那个数值。它能更好地代表一组数据的“一般水平”,因为它不受极端值的影响。
- 计算方法:
- 首先,必须将数据排序。
- 如果数据个数
n
是 奇数,中位数就是第(n+1)/2
个数据。 - 如果数据个数
n
是 偶数,中位数就是中间两个数(第n/2
个和第n/2 + 1
个)的平均值。
- 在这道题里,我们巧妙地利用了中位数的定义,通过构造一个有重复元素的短数组,来强制让中位数为
b
。
构造算法 (Constructive Algorithms)
- 概念:这是一类算法问题,它不要求你找到一个最优解,甚至不要求你找到所有解,而仅仅是要求你构造出任意一个满足所有给定条件的解。
- 解题思路:
- 简化问题:尝试固定一些变量,比如数组的长度,或者数组中某些元素的值,让问题变得更容易求解。
- 从最简单的情况入手:就像我们先考虑长度为 1 的数组一样。
- 寻找规律或模式:通过对小规模数据的分析,找到一个通用的构造方法。
- 大胆假设:比如我们假设数组里有重复的元素,这大大简化了我们的计算。
- 构造题考验的是我们的数学直觉和化繁为简的能力。当看到题目说“任意解即可”时,就应该立刻想到往最简单的方向去构造,不要想得太复杂啦,喵~
好啦,今天的讲解就到这里啦!希望 A-May 酱的礼物能让 A-Ming 开心。也希望各位 Master 能够喜欢这次的讲解,并且有所收获哦!如果觉得猫娘讲得还不错,就给个好评吧,喵呜~ (´,,•ω•,,)♡