1 条题解
-
0
📝 题目大意
给定整数 ,求所有满足 的非负整数三元组 中, 的最小值。
💡 解题思路
-
题目分析:, 均为非负整数。直接枚举三元组不可能,但 的范围很小—— 指数增长,当 时 只能为 ,此时 ,而 时取 已经得到 。因此 只需枚举 到 ,约 个值,完全可以暴力。
-
算法推导:
- 固定 时的最优策略:对于给定的 ,我们需要最小化 (因为 固定)。由 可得 ,因此 。
- 因为 ( 时等于 , 时大于 ), 关于 单调不增—— 越大, 越小(或不变)。
- 同时 要求 ,即 。所以 的最大可行值就是 (整除),此时 。
- 因此对于每个 ,最优三元组为 ,对应的目标值为 。
- 枚举所有 使得 ,取最小值即可。代码中
mul维护 ,b从 递增,每次ans = min(ans, n / mul + b + n % mul)。
-
边界与细节:
- 的情况:,此时 ,,。这是所有解的上界。
- : 时 ,答案为 。 时 ,循环退出。
- 溢出:,答案在
long long范围内,无需取模。初始ans设为9e18(大于 )足够安全。 - 循环终止条件:
while (mul <= n)在 时退出。此时若继续枚举,,目标值为 ,不会优于 时的答案 ,因此提前终止是正确的。
⏱️ 复杂度分析
- 时间复杂度: 从 枚举到 ,共 次迭代,每次 运算,总复杂度 。
- 空间复杂度:仅使用常数个变量,。
💻 标准代码 (C++)
#include <bits/stdc++.h> using namespace std; long long n, a, b, c, ans = 9e18; // ans 初始化为极大值(9e18 > 10^18) int main(){ cin >> n; long long mul = 1; // mul = 2^b while (mul <= n){ // 当 2^b > N 时,a 只能为 0,不会更优 // 固定 b 时,最优的 a = n / mul, c = n % mul ans = min(ans, n / mul + b + n % mul); b++; // 指数加 1 mul *= 2; // mul = 2^{b} } cout << ans << '\n'; return 0; } -
- 1
信息
- ID
- 865
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者