1 条题解
-
0
完整题解(C++ 版本)
问题重述
我们需要用 个白瓶和 个黑瓶搭建一个边长为 的三角形框架。
- 边长为 的三角形需要 个球瓶
- 同一行的球瓶颜色必须相同
- 不同行的颜色可以不同
- 目标是最大化
关键观察
重要结论:对于集合 ,它的所有子集和可以覆盖从 到 的所有整数。
这意味着:对于任意一个 满足 ,我们都能找到 的一个子集,其元素和正好等于 。
可行性分析
设白瓶使用的行号集合和为 ,则黑瓶使用的行号集合和为 。
我们需要:
- (白瓶够用)
- (黑瓶够用)
即: [ S - b \le A \le w ]
同时 必须是 到 之间的某个整数,且由于子集和的可覆盖性,只要这个区间非空,就存在可行的 。
区间 非空的条件是: [ S - b \le w \quad \text{且} \quad S - b \le S \quad \text{(自动满足)} ]
而 等价于: [ S \le w + b ]
结论:可行条件就是总球瓶数足够: [ \boxed{\frac{k(k+1)}{2} \le w + b} ]
求解最大
解二次不等式: [ k^2 + k - 2(w+b) \le 0 ]
得到: [ k \le \frac{-1 + \sqrt{1 + 8(w+b)}}{2} ]
因此: [ k_{\max} = \left\lfloor \frac{-1 + \sqrt{1 + 8(w+b)}}{2} \right\rfloor ]
时间复杂度
每个测试用例 时间,总复杂度 。
注意事项
- ,所以 最大可达 ,需要用
long long类型 - 使用
sqrt函数计算平方根,结果取整即可
完整代码(带注释)
#include <iostream> #include <cmath> using namespace std; int main() { int t; cin >> t; while (t--) { long long w, b; cin >> w >> b; long long total = w + b; // 总球瓶数 // 解方程 k(k+1)/2 <= total // 即 k^2 + k - 2*total <= 0 // k = floor((-1 + sqrt(1 + 8*total)) / 2) long long k = (sqrt(1 + 8 * total) - 1) / 2; cout << k << endl; } return 0; }
- 1
信息
- ID
- 7009
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者