欧几里得算法
部分内容转载于:欧几里得算法(辗转相除法)原理
**辗转相除法:**以大数除以小数,如果能整除,那么小数就是所求的最大公约数(Greatest CommonDivisor:gcd)。否则就用余数来除刚才的除数;再用这新除法的余数去除刚才的余数。依此类推,直到一个除法能够整除,这时作为除数的数就是所求的最大公约数。即:gcd(x,y)表示x与y的最大公约数,有gcd(x,y)=gcd(y,x%y),如此便可把原问题转化为求两个更小数的公约数,直到其中一个数为0,剩下的另外一个数就是两者的最大公约数。
int gcd(int big_num, int small_num)
{//最大公约数(欧几里得算法)
return small_num ? gcd(small_num, big_num%small_num) : big_num;
}
int lcm(int big_num, int small_num)
{//最小公倍数
return big_num * small_num / gcd(big_num, small_num);
}
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有d|a, d|b (表示a,b 能够zhen整除d) r = a - kb,因此d|r
因此d是(b,a mod b)的公约数 (试想为什么写(b,a mod b ),而不写(a,a mod b )?) -------疑问1
假设d 是(b,a mod b)的公约数,则d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。
答疑1 :因为 a = kb + r,b 和 r 的公约数一定就是被a整除,也一定是(a,b)公约数。如果写成(a,a mod b )的话,不能保证r能被b
整除。
2 ?为什么终止条件是b=0?
因为(a,b) 和(b,r)有共同的一样公约数,最大公约数就是r
例题
hrbust—1328:相等的最小公倍数
相关思路参考
分析:
两公倍数相等,则n能整除A(n-1),即n中有一个因子对能被之前的因子(A(n-1)的组成因子)抵消。
若n为素数,则前n位的最小公倍数必不等于前n-1位的最小公倍数,n为新的因子;
若n不为素数,则n=a*b:
从因子抵消的角度来看,当a和b分别被之前的因子抵消的时候,两者的最小公倍数才相等,否则,必出现新的因子使最大公倍数改变,所以,n的因子对(a,b)必互素,若其所有因子对均不互素,则a和b必存在公因子,所以构成四因子:a1,c,c,b1。由于c只能被抵消一个,所以会多出新的因子c,公倍数改变。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
using namespace std; //使用名称空间std
int main()
{
int gcd(long long a, long long b);
int find(long long n);
long long n;
int T;
scanf("%d", &T);
while (T--)
{
scanf("%lld", &n);
if (find(n))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
int gcd(long long a, long long b)
{//最大公约数
return b ? gcd(b, a%b) : a;
}
int find(long long n)
{
for (long long i = 2;i < n / 2+1;i++)
{
if (n%i == 0 && gcd(n / i, i) == 1)
return 1;
}
return 0;
}