题目

AC 代码

#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;

int main() 
{
    ll a, b;
    cin>>a>>b;

    ll d=abs(a-b);
    if(d==0)
    {
        if(a==1)
          cout<<1<<endl;
        else
          cout<<0<<endl;
        return 0;
    }

    if(d==1)cout<<-1<<endl;
    else
    {
        vector<ll> v;
        for(ll i=2;i*i<=d;i++)
        {
            if(d%i==0)
            {
                v.push_back(i);
                while(d%i==0)
                {
                    d=d/i;
                }
            }
        }
        if(d>1)v.push_back(d);

        ll ans = 1e18;
        for(auto& x:v)
        {
            ans=min(ans,(x-a%x)%x);
        }
        cout<<ans<<endl;
    }

    return 0;
}

个人见解

由题意,假设有一数字 g,令 A = a + c,B = b + c,我们希望得到 g | Ag | B ,即 g 整除 Ag 整除 B,因此有:


A = k_1×g,B = k_2×g \\
↓ \\
|A - B| = (k_1 - k_2)×g \\
↓ \\
|a - b| = (k_1 - k_2)×g

if(d==0)
{
    if(a==1)
      cout<<1<<endl;
    else
      cout<<0<<endl;
    return 0;
}

这里的判断需要小心 a=b=1 的情况,此时只需要 +1 即可让 gcd 变成 2

if(d==1)cout<<-1<<endl;
else
{
    vector<ll> v;
    for(ll i=2;i*i<=d;i++)
    {
        if(d%i==0)
        {
            v.push_back(i);
            while(d%i==0)
            {
                d=d/i;
            }
        }
    }
    if(d>1)v.push_back(d);

    ll ans = 1e18;
    for(auto& x:v)
    {
        ans=min(ans,(x-a%x)%x);
    }
    cout<<ans<<endl;
}

这是代码的核心部分,如果 d==1 当然直接输出 -1。否则,需要循环寻找 d 的因子,与普通寻找因数不同的是,本题只需要存储质因子,因为我们只想找到最小的 a+cb+c

if(d%i==0)
{
    v.push_back(i);
    while(d%i==0)
    {
        d=d/i;
    }
}

因此,只要 d \% i==0 就直接推入 vector 容器,然后利用 while 循环剔除所有因子 i ,这也是在保证往后出现的 i 一定是质因子的原因。

if(d>1)v.push_back(d); 

因为 d 的值在变化,可能会出现 d>1 但是 i*i>d 的情况,如果不加这行会遗漏关键的一个质因子!!!

ll ans = 1e18;
for(auto& x:v)
{
    ans=min(ans,(x-a%x)%x);
}

这里就是在寻找最小 c 的过程了,注意这里的表达式 (x-a\%x)\%xa\%x 表示a 大出 x 的数值,而 x-a\%x 表示距离凑出下一个 x 的倍数需要补齐的数字,那么为什么要再对 x 取模呢?举个例子,如果a == x,a\%x==0 ,此时 x-a\%x == x,但真实情况是由于 a 可以整除 x,所以x 此时不需要补齐任何数字,因此最后再对 (x-a\%x) 进行取模,即 (x-a\%x)\%x