1 条题解
-
0
📝 题目大意
黑板上有三个非负整数 。每次操作可以任选两个数各减 ,或者三个数全部减 。判断能否将所有数变为 ,若能则输出最小操作次数。
💡 解题思路
-
题目分析:
- 两种操作的本质:操作二(全减)每次消耗总和 ,操作一(选二减)每次消耗总和 。操作二"效率更高",但受限于不能使任何数变为负数。
- 设排序后 。每个操作至多使 减少 ,因此操作次数下界为 。
- 数据范围 ,必须使用
long long,且需要 的数学判定。
-
算法推导:
- 核心思路:尝试构造恰好 次操作的方案,因为 是理论下界,若能达成则必为最优。
- 构造策略:
- 先用操作一选 ,执行 次,使最大数降到与中间数持平。此时三个数变为:$$s' = s - (b - m),\quad m' = m,\quad b' = b - (b - m) = m$$
- 现在 ,再用操作二(全减)执行 次,将最小数清零。此时三个数变为:
- 最后用操作一选剩余两个数,执行 次,全部归零。
- 总操作次数:$$(b - m) + s' + (m - s') = (b - m) + s' + m - s' = b$$恰好达到下界。
- 可行性条件:上述构造要求 ,即 。等价于 (三角形不等式)。
- 若 ,则无论如何操作, 都会在 和 差距抹平之前变为负数,不可行,输出 。
- 该推导与
std.cpp的判定逻辑完全一致:small >= (big - mid)时输出big,否则输出-1。
-
边界与细节:
- 全零情况:,排序后 , 成立(),输出 ,正确。
- 一个非零、其余为零:如 ,,(),输出 ,正确。
- 溢出: 最大 ,
big - mid和比较运算均在long long范围内,不会溢出。
⏱️ 复杂度分析
- 时间复杂度:仅需排序三个数()和一次比较(),总体 。
- 空间复杂度:仅存储三个
long long变量,。
💻 标准代码 (C++)
#include <bits/stdc++.h> using namespace std; int main() { vector<long long> que(3); // 存储三个输入数 for (long long i = 0; i < 3; ++i) cin >> que[i]; sort(que.begin(), que.end()); // 升序排序,得到 small ≤ mid ≤ big long long small = que[0], mid = que[1], big = que[2]; // 核心判定:最小值是否足以填补最大值与中间值的差距 if (small >= (big - mid)) cout << big; // 可行,最小操作次数即最大值 else cout << -1; // 不可行 return 0; } -
- 1
信息
- ID
- 875
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者