P a r t Part Part 1 1 1 读题
给出某两个整数 a a a和 b b b( a ≤ b a≤b a≤b)的最大公约数 G C D GCD GCD和最小公倍数 L C M LCM LCM,请找出满足的 a a a和 b b b,使得 b − a b-a b−a的值最小。
输入格式
输入数据只有一行,包括两个整数 G C D GCD GCD和 L C M LCM LCM。输入保证至少存在一组解。
输出格式
输出包含一个整数,为最小的 b − a b-a b−a的值。
输入样例1
6 36
输出样例1
6
输入样例2
114514 1919810
输出样例2
1717710
数据范围与提示
1 ≤ a , b ≤ 1 0 9 1≤a,b≤10^9 1≤a,b≤109
P a r t Part Part 2 2 2 思路
本题是一道纯正的数学推理题涉及到数学知识的题目,和作者原来写的两数问题(点我)有点像,都是给出原数的最大公因数和最小公倍数,区别在于一个是求满足条件的两数的个数,一个是求两数最小的差。
那我们正式开始解题。
首先就是求两数的是最大公因数和最小公倍数(点我看方法),然后我们就遇到一个问题:怎么求 b − a b-a b−a的最小值。我们一步步来分析。
在只知道 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 a−b就可以表示为 g c d × x − g c d × y gcd\times x-gcd\times y gcd×x−gcd×y,也就是 g c d × ( x − y ) gcd\times (x-y) gcd×(x−y)。由于 x x x和 y y y是整数, g c d × ( x − y ) gcd\times (x-y) gcd×(x−y)的最小值为 g c d gcd gcd(在 x = y x=y x=y的情况下),在满足最大公约数和最小公倍数的条件下, b − a b-a b−a的最大值是 l c m ÷ g c d lcm÷gcd lcm÷gcd。
接下来该循环去遍历上面说的 x x x和 y y y了,我们需要从 1 1 1遍历到 b − a b-a b−a的最大值(也就是 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;
}
听完后,是不是觉得很简单呢?赶快自己去试一下吧!!!
作者写公式不容易,麻烦点个赞支持下吧