题目链接
题意:输入两个数 a, b
,让你求可以使得(a+k)与 (b+k)的最小公倍数最小的情况下的最小的k
.
思路: lcm(a+k, b+k) = (a+k)*(b+k)/gcd(a+k, b+k)
,又gcd(a+k, b+k) = gcd(a-b, a+k)
,令d = gcd(a+k, b+k)
,则 d
一定为a-b
的因子,若知道d
则可以求出k = d - a%d
,也就可以求出lcm(a+k, b+k)
,所以我们选择暴力的方式去遍历a-b
的因子,再取这个最小lcm
对应的k
就是答案。
d = gcd(a-b, a+k)
,求出k
的过程 =>(a+k)%d = 0; 即((a % d + k % d) % d = 0),所以 a%d + k%d = d 或者 a%d + k%d = 0,令 a = x*d + r, k = y*d + s,则(x*d + r) % d + (y*d + s) % d = d 或者(x*d + r) % d + (y*d + s) % d = 0;即 r + s = d 或者 r + s = 0。由于 k = y*d + s 要最小值,所以 k = s,所以 r + k = d 或者 r + k = 0; 而 r = a%d,所以 k = d - a%d
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define show(x) cout<<x<<endl;
#define show_(x) cout<<x<<" ";
#define showEnd(x) {cout<<x<<endl; return 0;}
#define showxy(x, y) cout<<x<<" "<<y<<endl;
typedef long long ll;
typedef pair<int, int> iip;
typedef pair<ll, ll> llp;
const int MAXN = 1000005;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
int i, j, a, b, ans;
vector<int> v;
struct node {
ll lcm;
int k;
bool operator < (const node &y) const {
if(lcm == y.lcm) return k < y.k;
return lcm < y.lcm;
}
}x[MAXN];
ll gcd(ll x, ll y) {
return y == 0 ? x : gcd(y, x % y);
}
ll LCM(ll x, ll y) {
return x * y / gcd(x, y);
}
int main()
{
IO
cin>>a>>b;
if(a < b) swap(a, b);
int tmp = a - b;
for(i = 1; i * i <= tmp; i++) {
if(tmp % i == 0) {
v.push_back(i);
if(i != tmp/i) v.push_back(tmp / i);
}
}
i = 0;
for(int d : v) {
x[i].k = d - a % d;
x[i++].lcm = LCM((a + x[i].k) , (b + x[i].k));
}
x[i].k = 0;
x[i++].lcm = LCM(a, b);
sort(x, x+i);
cout<<x[0].k<<'\n';
return 0;
}