CF1152C Neko does Maths

题目描述

(描述为翻译,翻译来自洛谷)
给定两个正整数a,b,找到非负整数k使a+k与b+k的最小公倍数最小,如有多解输出最小的k

a , b ≤ 1 0 6 a ,b ≤ 10^6 a,b106
对于这种题我们显然需要一些数论知识来帮助我们找到思路
那么我们首先想到的是lcm和gcd是有关系的
l c m ( a , b ) = a ∗ b g c d ( a , b ) lcm(a,b) = \frac{a*b}{gcd(a,b)} lcm(a,b)=gcd(a,b)ab
那么在这道题中就是 l c m ( a + k , b + k ) = ( a + k ) ∗ ( b + k ) g c d ( ( a + k ) , ( b + k ) ) lcm(a+k, b+k) = \frac{(a+k) * (b+k)}{gcd((a+k), (b+k))} lcm(a+k,b+k)=gcd((a+k),(b+k))(a+k)(b+k)
然后我们可以想到gcd的一些性质
那么由更相减损术我们可以知道 g c d ( a , b ) = g c d ( b , a − b ) gcd(a,b) = gcd(b,a-b) gcd(a,b)=gcd(b,ab)其中,a >b;
那么我们就可以把原式子中的 g c d ( a + k , b + k ) gcd(a+k,b+k) gcd(a+k,b+k)写成 g c d ( b + k , a − b ) gcd(b+k, a-b) gcd(b+k,ab)
那么我们考虑,设 x = g c d ( b + k , a − b ) x = gcd(b+k, a-b) x=gcd(b+k,ab)那么x一定是a-b的因子的其中一个,这时候我们只需要算出一个k使x是b+k和a-b的gcd我们就可以求出一个lcm,
这里当 b m o d    x = = 0 b\mod x == 0 bmodx==0时k = 0;
!=时 k = b/x * x + x; 这里的除是向下取整,这样就保证了x是b+k的最大因子。
因此我们可以枚举a-b的所有因子,求出对应的k和lcm,对于每个结果进行比较求min即可。

没想到的是,k是会爆ll的 所以记得开ll写

C o d e Code Code

#include<bits/stdc++.h>

#define INF 0x3f3f3f3f
#define ll long long

using namespace std;

inline ll gcd(ll a, ll b){//没用
	return a % b == 0 ? b : gcd(b, a % b);
}


ll a, b, k, t;
ll ans = 1e18;

int main()
{
	cin >> a >> b;
	if(a < b){
		a ^= b, b ^= a, a ^= b;
	}
	ll num = 1e18;
	
	for(ll i = 1; i * i <= a-b; ++i){//i,j都为枚举的因子
		ll tk;
		if((a-b) % i == 0){
			ll j = (a-b) / i;
			
			if(b % i == 0) tk = 0;
			else tk = (b / i + 1) * i - b;
			
			ll num = (a + tk) * (b + tk) / i;
			
			if(num < ans) ans = num, k = tk;
			if(num == ans) k = min(k, tk);

			if(b % j == 0) tk = 0;
			else tk = (b/j + 1) * j - b;
			
			num = (a + tk) * (b + tk) / j;
			if(num < ans) ans = num, k = tk;
			
			else if(num == ans) k = min(k, tk);
		}
	}
	cout << k << endl;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIGBIGPPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值