最大公因数 最小公倍数
/**
Function:数论-最大公因数 最小公倍数 Date:2017-2-9
Compiler:CodeBlocks16.01
*/
#include "iostream"
#include "string"
#include "cstdio"
using namespace std;
1.最大公约数/因数(GCD Greatest Common Divisor)
最小公倍数(LCM Lowest Common Multiple )
假设a和b都是正整数,且a > b
a = bq + r , 0 < r < b
其中q和r都是正整数,则a和b的最大公因数等于b和r的最大公因数,即
( a , b )=( b , r )
即
欧几里德算法(辗转相除法):
递归法
迭代法
最小公倍数:
LCM(a,b)=a*b/GCD(a,b)
推论:
GCD(a,b)=GCD(a+b,LCM(a,b))
LCM(M*a,M*b)=M*GCD(a,b)
1 int gcd(int a,int b) 2 { 3 ///法一:迭代 4 int r=0,t=0; 5 while(b!=0){ 6 t=a; 7 a=b;///以b代替a =bq1+r1 (a,b)=(b,r1) 8 r=b;///余数 9 b=t%b;10 } 11 return r; 12 ///法二:递归 13 //return b==0?a:gcd(b,a%b); 14 }
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2383
/**题意:
知两正整数G,L,输出以L为最小公倍数,以G为最大公因数的一对数(若有多组输出a最小的那一组),无输出-1
*/
/**逆用 逆推
设:a=G*x,b=G*y
则L=G*x*G*y/G=G*x*y
L/G=x*y ->L%G=0
则x=1,a=G,b=L;(因为a最小,x,y互质,所以x=1;)
若L/G不为正整数,-1
*/
1 int main() 2 { 3 int G=0,L=0; 4 int T; 5 scanf("%d",&T); 6 while(T--){ 7 scanf("%d%d",&G,&L); 8 if(L%G==0){ 9 printf("%d %d\n",G,L); 10 }else{ 11 printf("-1\n"); 12 } 13 } 14 return 0; 15 }
http://acm.hit.edu.cn/hoj/problem/view?id=2010
/**题意:
知两正整数G,L,(假设所有整数小于2^63-1)输出以L为最小公倍数,以G为最大公因数
的一对数(若有多组输出a+b最小的那一组),无输出-1
找规律,a+b最小即a与b最接近
问题变为把lcm/gcd分解为两个互质的数的乘积。
这样就可以枚举了,从lcm/gcd的平方根开始枚举a即可。
由于数据比较大,所以用了long long
*/
1 long long gcd(long long a,long long b) 2 { 3 return b==0?a:gcd(b,a%b); 4 } 5 #include "cmath" 6 int main() 7 { 8 long long G,L; 9 while(~scanf("%lld%lld",&G,&L)) 10 { 11 long long temp=L/G,y=0;///两数乘积temp 12 long long i; 13 for(i=sqrt(1.0*temp);i>=1;i--) 14 { 15 if(temp%i==0){ 16 y=temp/i; 17 if(gcd(y,i)==1){ 18 break; 19 } 20 } 21 } 22 printf("%lld %lld\n",i*G,y*G); 23 } 24 return 0; 25 }