求使得lcm(a+k,b+k)最小的时候的最小k。
根据同余定理。
a%c==0 b%c == 0 --》(a-b)%c ==0
所以gcd(a,b)=gcd(a,fabs(b-a))
这个题目中 b-a是固定的,所以gcd(a+k,b+K)的值就在于a+k与b-a的关系。
我们知道,如果a+k有b-a的因数那么gcd就能变得更小。
基于这个,我们遍历所有b-a的因数,来寻找是的lcm最小的时候的最小k。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
char ch = getchar(); int x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
ll a, b;
ll dist;
ll ans = 0;
ll sum = 1e15;
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a%b);
}
int main()
{
cin >> a >> b;
if (a > b)swap(a, b);//a大b小
if (b%a == 0) { cout << 0 << endl; return 0; }//是倍数的时候就不需要判断了
dist = b - a;//距离
if (dist < a)//距离比a小,那么a肯定能化成dist的倍数,此时gcd=dist肯定是最小的
{
cout << (dist - a % dist) % dist << endl;//再模一下就能保证输出再0-dist-1
return 0;
}
else
{
for (int i = 1; i*i <= dist; i++)
{
if (dist%i == 0)//如果是因数
{
ll temp = i - (a%i);//算k值
ll sumtemp = (a + temp)*(b + temp) / gcd(a + temp, b + temp);
if (sumtemp == sum)
{
if (temp < ans)ans = temp;
}
if (sumtemp < sum)
{
sum = sumtemp;
ans = temp;
}
temp = dist / i - (a % (dist / i));//判断dist/i的大小
sumtemp = (a + temp)*(b + temp) / gcd(a + temp, b + temp);
if (sumtemp == sum)if (temp < ans)ans = temp;
if (sumtemp < sum)sum = sumtemp, ans = temp;
}
}
cout << ans << endl;
}
return 0;
}
不过看别人的代码发现有更简单的方法,虽然思路差不多,不过我看大佬连gcd都没有用上。
大概就是
ans=min(ans,i-a)
ans=min(ans,dist/i-a)。。没太明白为什么这样就一定能满足