题目描述
给定两个正整数 和
,你可以选择任意正整数
,将其同时加到
与
上,得到
与
。你的目标是使
尽可能小。请你输出能够达到的最小值。
核心思路
核心观察
-
差值不变性:无论
取何值,两数之差始终为
。
-
最大公约数(gcd):
一定是
的约数。
-
最优策略:让
是
的倍数,并且尽可能小。
-
数论恒等式:
-
可得:
- 令
,
,则目标函数为:
-
-
特殊情况处理
-
当
:
,不能用上述方法
- 此时
,所以
- 比值恒为
-
当
(即
):
- 取
- 则新数对为
,比值为
- 这是除
外的理论最小值
- 取
-
算法步骤
- 如果
,直接输出 1。
- 如果
,输出 2。注意没有等于
- 否则,计算最小正整数
使得
(a+x的整体可以被d整除的意思),并计算比值
,因为小的数是k,那么大的数就是k+1。
正确性分析
- 当
时,
,比值恒为 1。
- 当
时,可以构造
形式的数对,使得比值为 2。
- 对于一般情况,通过计算
使得
,并计算比值
。
复杂度分析
- 时间复杂度:每个测试用例的时间复杂度为
,因为所有操作都是常数时间内完成的。
- 空间复杂度:每个测试用例的空间复杂度为
,因为只使用了常数级别的额外空间。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
int t;
cin >> t;
while (t--) {
int a, b;
cin >> a >> b;
if (a == b) {
cout << "1\n";
continue;
}
if (abs(a - b) > min(a, b)) {
cout << "2\n";
continue;
}
if (a > b) swap(a, b);
int d = b - a;
int k = a / d + 1; // 计算最小 x 使得 d | (a + x)
cout << k * (k + 1) << '\n';
}
return 0;
}
温馨提示:别忘了开longlong

京公网安备 11010502036488号