•题意
给出两个正整数 a,b;
求解 k ,使得 LCM(a+k,b+k) 最小,如果有多个 k 使得 LCM() 最小,输出最小的k;
•思路
时隔很久,又重新做这个题
温故果然可以知新❤
重要知识点
GCD(a,b)=GCD(a,b-a)=GCD(b,b-a) (b>a)
证明:
设GCD(a,b)=c
则a%c=0,b%c=0,(b-a)%c=0
所以GCD(a,b-a)=c
得GCD(a,b)=GCD(a,b-a)
思路一:
gcd(a+k,b-a)肯定是(b-a)的因子
所以gcd(a+k,b+k)是(b-a)的因子,所以我们就枚举(b-a)的因子(把因子称为i)
使得 (a+k)为i的倍数
解出k,再判断lcm是否符合最小
注意这里枚举的i只是(a+k)和(b+k)的公约数,不一定是最大公约数gcd
两者的公约数得到的是公倍数 公倍数=a*b/公约数
如果是最大公约数的话两者的公倍数一定是最小,
这里是没有甄别是否是最大公约数而是简单的得到公约数,然后得到的是公倍数
在所有的公倍数中,最小公倍数是最小的
所以并不影响解最小公倍数的答案
例如:
12 30
12 30
a+k=13 b+k=31 公约数i=1 公倍数=403 k=1
a+k=18 b+k=36 公约数i=18 公倍数=36 k=6
a+k=14 b+k=32 公约数i=2 公倍数=224 k=2
a+k=18 b+k=36 公约数i=9 公倍数=72 k=6
a+k=15 b+k=33 公约数i=3 公倍数=165 k=3
a+k=18 b+k=36 公约数i=6 公倍数=108 k=6最小公约数36,此时k=6
•代码
View Code1 //#include<bits/stdc++.h> 2 //using namespace std; 3 //#define ll long long 4 //#define inf 0x3f3f3f3f 5 //ll ans=inf; 6 //ll a,b; 7 //ll lcm; 8 // 9 //ll __lcm(ll x,ll y) 10 //{ 11 // return x*y/__gcd(x,y); 12 //} 13 // 14 // 15 //void Slove(int f) 16 //{ 17 // int x=a/f+(a%f!=0); 18 // int y=(b-a)/f; 19 // if(__gcd(x,y)==1) 20 // { 21 // if(__lcm(x*f,y*f)<lcm) 22 // { 23 // lcm=__lcm(x*f,y*f); 24 // ans=x*f-a; 25 // } 26 // if(__lcm(x*f,y*f)==lcm) 27 // ans=min(ans,x*f-a); 28 // } 29 // else 30 // { 31 // if(__lcm((x+1)*f,y*f)<lcm) 32 // { 33 // lcm=__lcm((x+1)*f,y*f); 34 // ans=(x+1)*f-a; 35 // } 36 // if(__lcm((x+1)*f,y*f)==lcm) 37 // ans=min(ans,(x+1)*f-a); 38 // } 39 //} 40 // 41 //int main() 42 //{ 43 // cin>>a>>b; 44 // if(b<a) 45 // swap(a,b); 46 // lcm=a*b/__gcd(a,b); 47 // 48 // if(a==b) 49 // ans=0; 50 // else 51 // { 52 // for(ll i=1;i*i<=b-a;i++) 53 // { 54 // if((b-a)%i==0) 55 // { 56 // Slove(i); 57 // Slove((b-a)/i); 58 // } 59 // } 60 // } 61 // cout<<ans<<endl; 62 //} 63 64 65 #include<bits/stdc++.h> 66 using namespace std; 67 #define ll long long 68 ll a,b; 69 ll ans,lcm=0x3f3f3f3f3f3f3f3f; 70 int main() 71 { 72 cin>>a>>b; 73 ll d=abs(a-b); 74 for(ll i=1;i*i<=d;i++) 75 { 76 if(d%i==0)//枚举b-a的因数i 77 { 78 ll k=i-a%i;//把a凑成i的倍数需要+k 79 ll t=(a+k)*(b+k)/i;// a*b/i得公倍数 80 if(t<lcm) 81 { 82 lcm=t; 83 ans=k; 84 } 85 86 ll ii=d/i; 87 k=ii-a%ii; 88 t=(a+k)*(b+k)/ii; 89 if(t<lcm) 90 { 91 lcm=t; 92 ans=k; 93 } 94 } 95 } 96 cout<<ans<<endl; 97 }