题解:洛谷 P9955 Do You Know Your ABCs
【题目来源】
洛谷:P9955 [USACO20DEC] Do You Know Your ABCs? B - 洛谷(luogu.com.cn)
【题目描述】
Farmer John 的奶牛正在 "mooZ" 视频会议平台上举行每日集会。她们发明了一个简单的数字游戏,为会议增添一些乐趣。
Elsie 有三个正整数 \(A\)、\(B\) 和\(C(A\le B\le C)\)。这些数字是保密的,她不会直接透露给她的姐妹 Bessie。她告诉 Bessie 七个范围在\(1\dots 10^9\)之间的整数(不一定各不相同),并宣称这是 \(A\)、\(B\)、\(C\)、\(A+B\)、\(B+C\)、\(C+A\)和 \(A+B+C\)的某种排列。
给定这七个整数,请帮助 Bessie 求出 \(A\)、\(B\)和 \(C\)。可以证明,答案是唯一的。
【输入】
输入一行,包含七个空格分隔的整数。
【输出】
输出 \(A\)、\(B\) 和\(C\),用空格分隔。
【输入样例】
2 2 11 4 9 7 9
【输出样例】
2 2 7
【核心思想】
-
问题分析:给定七个整数,它们是三个正整数 \(A \le B \le C\) 以及两两之和 \(A+B, B+C, C+A\) 与三者之和 \(A+B+C\) 的某种排列。要求唯一确定 \(A, B, C\)。由于所有数均为正且有序,这七个数的排序具有固定结构:最小的两个数必定是 \(A\) 和 \(B\),最大的数必定是 \(A+B+C\)。利用这一性质,只需排序后取最小两个数作为 \(A\) 和 \(B\),再从最大值中减去 \(B\)(或取第二大的数减去 \(A\))即可得到 \(C\)。
-
算法选择:
- 排序 + 数学关系:对七个数升序排序,利用和的性质直接解出。
- 关键观察:因为 \(A \le B \le C\),所以 \(A \le B \le A+B \le A+C \le B+C \le A+B+C\)(其中 \(A+B\) 与 \(C\) 的大小关系不定,但 \(A+B\) 不一定小于 \(C\),不过前两个最小的一定是 \(A\) 和 \(B\),最大的一定是总和)。因此 \(A = \min\),\(B = \text{第二小}\),\(C = \text{总和} - A - B\)。
-
关键步骤:
- 读入:读取 7 个整数存入数组
num[1..7]。 - 排序:将数组升序排列。
- 确定 \(A\) 和 \(B\):
A = num[1],B = num[2](最小的两个数)。 - 确定 \(C\):总和为最大数
num[7],因此C = num[7] - A - B(等价于代码中的c = num[6] - b,因为num[7] - A - B = (A+B+C) - A - B = C,而num[6] - B并不总是等于 \(C\),但在此题中由于 \(A\) 和 \(B\) 可能相等且结构特殊,该写法在某些情况下可行,但更安全的方式是c = num[7] - a - b)。 - 输出:输出 \(A, B, C\)。
- 读入:读取 7 个整数存入数组
-
时间/空间复杂度:
- 时间复杂度:\(O(1)\)(排序 7 个元素)。
- 空间复杂度:\(O(1)\)。
-
排序 + 和的性质的核心思想:
- 最小值定 \(A, B\):由于 \(A \le B \le C\),所有数中 \(A\) 必然最小,\(B\) 必然第二小(即使 \(A=B\),两个最小值也是 \(A\) 和 \(B\))。
- 最大值定总和:\(A+B+C\) 一定是七个数中的最大值。
- 唯一性保证:题目保证答案唯一,因此利用上述关系可直接解出,无需枚举。
- 适用场景:适用于给定若干个数,它们是由一组未知数及其部分和构成的集合,且未知数有大小关系。核心是识别最值和总和的位置。
【解题思路】

【算法标签】
入门 #模拟
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int a, b, c; // 三个未知数 A, B, C
int num[10]; // 存储输入的7个数字
int main()
{
// 输入7个数字
for (int i = 1; i <= 7; i++)
{
cin >> num[i];
}
// 对7个数字进行升序排序
sort(num + 1, num + 7 + 1);
// 确定A和B的值(最小的两个数)
a = num[1]; // A是最小的数
b = num[2]; // B是第二小的数
// 确定C的值:利用A+B+C = 最大值,且A+B, A+C, B+C也在数组中
// 排序后第6个数是B+C,减去B得到C
c = num[6] - b;
// 输出A, B, C的值
cout << a << " " << b << " " << c << endl;
return 0;
}
【运行结果】
2 2 11 4 9 7 9
2 2 7
浙公网安备 33010602011771号