链接:https://codeforces.com/contest/1152/problem/C
题意:给两个数a和b,找到一个最小的k,使得a+k和b+k的lcm最小
题解:假设a>b,gcd(a,b)=gcd(b,a-b),所以我们要求的gcd(a+k,b+k)可以转化成gcd(b+k,a-b),令d=gcd(b+k,a-b),则d是a-b的因数,枚举这个因数,枚举过程中不断更新最小的lcm对应的k,若lcm相等,就直接更新最小k
代码:
1 //#include<bits/stdc++.h> 2 #include<iostream> 3 #include<vector> 4 #include<stack> 5 #include<string> 6 #include<cstdio> 7 #include<algorithm> 8 #include<queue> 9 #include<map> 10 #include<set> 11 #include<cmath> 12 #include<iomanip> 13 #define inf 0x3f3f3f3f 14 using namespace std; 15 typedef long long ll; 16 const int M = int(1e7) * 2 + 5; 17 ll gcd(ll a, ll b) 18 { 19 return b ? gcd(b, a % b) : a; 20 } 21 ll lcm(ll a, ll b) 22 { 23 return a * b / gcd(a, b); 24 } 25 ll d, k, tem; 26 signed main() 27 { 28 ll a, b; cin >> a >> b; 29 ll c = abs(a - b); 30 if (a < b) swap(a, b); 31 vector<ll> div; 32 for (ll i = 1; i * i <= c; i++) { //筛出a-b的因数 33 if (c % i == 0) 34 div.push_back(i); 35 if (i * i != c)//判断是否为平方数 36 div.push_back(c / i); 37 } 38 if (a == b){ //特判a=b的情况 39 cout << 0 << endl; 40 return 0; 41 } 42 sort(div.begin(), div.end()); 43 ll ans = inf, tlcm = inf; 44 //cout << div.size() << endl; 45 d = div[0]; 46 k = (d - a % d) % d; //已知d求解k 47 tem = lcm(a + k, b + k); 48 ans = k; 49 tlcm = tem; 50 for (int i = 1; i < div.size(); i++) { //枚举所有的因数 51 d = div[i]; 52 k = (d - a % d) % d; 53 tem = lcm(a + k, b + k); 54 /*cout << i; 55 cout << "tem=" << tem << " " << "tlcm=" << tlcm << endl; 56 cout << "k=" << k << endl;*/ 57 if (tem < tlcm) { //以lcm最小为依据更新k 58 ans = k; 59 tlcm = tem; 60 } 61 else if (tem == tlcm) { 62 ans = min(ans, k); 63 } 64 //cout << "ans=" << ans << endl; 65 } 66 cout << ans << endl; 67 return 0; 68 }
备注:由于一开始inf设置过小,循环从0开始会导致在数据过大时无法更新lcm