【C++题解】GCD与LCM

P a r t Part Part 1 1 1 读题

题目描述

给出某两个整数 a a a b b b a ≤ b a≤b ab)的最大公约数 G C D GCD GCD和最小公倍数 L C M LCM LCM,请找出满足的 a a a b b b,使得 b − a b-a ba的值最小。

输入格式

输入数据只有一行,包括两个整数 G C D GCD GCD L C M LCM LCM。输入保证至少存在一组解。

输出格式

输出包含一个整数,为最小的 b − a b-a ba的值。

输入样例1

6 36

输出样例1

6

输入样例2

114514 1919810

输出样例2

1717710

数据范围与提示

1 ≤ a , b ≤ 1 0 9 1≤a,b≤10^9 1a,b109

P a r t Part Part 2 2 2 思路

本题是一道纯正的数学推理题涉及到数学知识的题目,和作者原来写的两数问题(点我)有点像,都是给出原数的最大公因数和最小公倍数,区别在于一个是求满足条件的两数的个数,一个是求两数最小的差。

那我们正式开始解题。

首先就是求两数的是最大公因数和最小公倍数(点我看方法),然后我们就遇到一个问题:怎么求 b − a b-a ba的最小值。我们一步步来分析。

在只知道 a a a b b b两数的最大公因数和最小公倍数的情况下,根据数学知识,我们知道 a = g c d × x a=gcd\times x a=gcd×x b = g c d × y b=gcd\times y b=gcd×y(此处的 x x x y y y是整数),那么 a − b a-b ab就可以表示为 g c d × x − g c d × y gcd\times x-gcd\times y gcd×xgcd×y,也就是 g c d × ( x − y ) gcd\times (x-y) gcd×(xy)。由于 x x x y y y是整数, g c d × ( x − y ) gcd\times (x-y) gcd×(xy)的最小值为 g c d gcd gcd(在 x = y x=y x=y的情况下),在满足最大公约数和最小公倍数的条件下, b − a b-a ba的最大值是 l c m ÷ g c d lcm÷gcd lcm÷gcd

接下来该循环去遍历上面说的 x x x y y y了,我们需要从 1 1 1遍历到 b − a b-a ba的最大值(也就是 l c m ÷ g c d lcm÷gcd lcm÷gcd)的开方(去重),如果最大值和遍历的值有倍数关系(此处就是说 x × y = x\times y= x×y=最大值,还有一个原因是要求 x x x y y y都是整数),那我们就可以求出对应的 x x x y y y,从而算出 a a a b b b的值。(可能这个地方大家不太懂,我来证明一下:根据数学知识,我们知道 a × b = l c m × g c d a\times b=lcm\times gcd a×b=lcm×gcd,那我们要把这个式子化简: g c d × x × g c d × y = l c m × g c d gcd\times x\times gcd\times y=lcm\times gcd gcd×x×gcd×y=lcm×gcd,所以得出 x × y = l c m ÷ g c d x\times y=lcm÷gcd x×y=lcm÷gcd)。同时我们要保证 x x x y y y两数互质,不然最后求出的数的 l c m lcm lcm g c d gcd gcd与题目给的 l c m lcm lcm g c d gcd gcd不一样。也就是如下代码:

mxc=lcmm/gcdd;//mxc指b-a的最大值,也就是lcm/gcd
for(int i=1;i<=sqrt(mxc);i++){//去重
	if(mxc%i==0){//有倍数关系
		x=i,y=mxc/i;//求出对应的x和y
		if(gcd(x,y)==1)a=gcdd*x,b=gcdd*y;//保证x、y两数互质 
	}
}

然后我们再加上定义、输入和输出就可以啦!

小tip:大家可以先根据思路,写一下代码哦!

P a r t Part Part 3 3 3 代码

#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
    if(b==0)return a;
    return gcd(b,a%b);
}
int gcdd,lcmm,a,b,x,y,mxc;//mxc指b-a的最大值,也就是lcm/gcd
int main(){
	cin>>gcdd>>lcmm;
	mxc=lcmm/gcdd;
	for(int i=1;i<=sqrt(mxc);i++){//去重
		if(mxc%i==0){//有倍数关系
			x=i,y=mxc/i;//求出对应的x和y
			if(gcd(x,y)==1)a=gcdd*x,b=gcdd*y;//保证x、y两数互质 
		}
	}
	cout<<b-a;
	return 0;
}

听完后,是不是觉得很简单呢?赶快自己去试一下吧!!!

作者写公式不容易,麻烦点个赞支持下吧

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值