排序后最小两个数是 A、B,最大数是 A+B+C,直接相减得到 C。
OJ: usaco
题目 ID: 1059
难度:入门
标签:数学排序枚举
日期: 2026-07-11 13:52
题意
有三个正整数 A、B、C,满足
现在给出下面 7 个数的乱序结果:
text
A, B, C, A+B, A+C, B+C, A+B+C要求还原并输出 A B C。
思路
朴素验证
可以先写一个直接枚举的版本:枚举输入中的三个值作为 A、B、C,生成 7 个数后排序,和输入排序后的多重集合比较。
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-11 13:52
* update_at: 2026-07-11 13:54
*/
// brute.cpp:小数据暴力解,用来帮助理解题意并辅助对拍。
#include <bits/stdc++.h>
using namespace std;
long long x[10]; // 输入的 7 个数
long long target[10]; // 排序后的输入多重集合
long long cur[10]; // 某组 A,B,C 生成出的 7 个数
bool same_multiset() {
for (int i = 0; i < 7; i++) {
if (cur[i] != target[i]) {
return false;
}
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
for (int i = 0; i < 7; i++) {
cin >> x[i];
target[i] = x[i];
}
sort(target, target + 7);
// 暴力枚举三个秘密数字分别等于输入中的哪个值,再检查能否生成同一个多重集合。
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
for (int k = 0; k < 7; k++) {
long long A = x[i];
long long B = x[j];
long long C = x[k];
if (!(A <= B && B <= C)) {
continue;
}
cur[0] = A;
cur[1] = B;
cur[2] = C;
cur[3] = A + B;
cur[4] = A + C;
cur[5] = B + C;
cur[6] = A + B + C;
sort(cur, cur + 7);
if (same_multiset()) {
cout << A << ' ' << B << ' ' << C << '\n';
return 0;
}
}
}
}
return 0;
}这个暴力能直接体现题意:我们要找的是能生成同一个多重集合的三元组。由于只有 7 个输入值,枚举候选值本身也很小;但正式解法可以更直接。
关键观察
把 7 个数排序。因为 A、B、C 都是正整数,任意两个数的和一定不小于其中的单个数,三个数的和一定最大。
又因为题目给出
text
排序后第 1 个数 = A
排序后第 2 个数 = B
排序后最后一个数 = A+B+C于是:
text
C = (A+B+C) - A - B所以只需要排序一次,就能得到答案。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-11 13:52
* update_at: 2026-07-11 13:54
*/
#include <bits/stdc++.h>
using namespace std;
long long a[10]; // 输入的 7 个数
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
for (int i = 0; i < 7; i++) {
cin >> a[i];
}
sort(a, a + 7);
long long A = a[0];
long long B = a[1];
long long C = a[6] - A - B;
cout << A << ' ' << B << ' ' << C << '\n';
return 0;
}复杂度
只排序 7 个数,时间复杂度可以看作
只保存 7 个数,空间复杂度为
总结
这题的重点是保留“正整数”和
它们让排序后的最小两个值和最大值都有确定含义,因此可以直接从极值推出 A、B、C。