Codeforces Round #554 (Div. 2) C. Neko does Maths 数论

题目链接
题意:输入两个数 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;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容