题解:洛谷 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

【核心思想】

  1. 问题分析:给定七个整数,它们是三个正整数 \(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\)

  2. 算法选择

    • 排序 + 数学关系:对七个数升序排序,利用和的性质直接解出。
    • 关键观察:因为 \(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\)
  3. 关键步骤

    • 读入:读取 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\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(1)\)(排序 7 个元素)。
    • 空间复杂度:\(O(1)\)
  5. 排序 + 和的性质的核心思想

    • 最小值定 \(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
posted @ 2026-08-30 09:19  团爸讲算法  阅读(10)  评论(0)    收藏  举报