2. 最大公约数(欧几里得算法/辗转相除法)

版权声明:本文为博主原创,未经博主允许不得转载 https://blog.csdn.net/Sherry_Yue/article/details/88061791

最大公约数(Greatest Common Divisor)

引题
输入两个自然数x、y,求它们的最大公约数。
对于两个整数x和y,如果x/d个y/余数都为0,则d称为x和y的公约数,其中最大的称为x和y的最大公约数(Greatest Common Divisor)。举个例子,35和14的最大公约数gcd(35,14)为7.因为35的约数为{1,5,7,35},14的约数为{1,2,7,14},二者的公约数{1,7}中最大的是7。

输入:输入x、y,用1个空格隔开,占1行。
输出:输出最大公约数,占1行。
限制 1 < = x , y < = 1 0 9 1<=x,y<=10^9
提示:对于整数x、y,如果x>=y,则x与y的最大公约数等于y与x%y的最大公约数。这里x%y表示x除以y之后的余数。
输入示例:147 105
输出实例:21

1. 初学者的思维:

将x和y中较小的一方用作n,让d从n自减至1,检查其是否能同时整除x和y,如果能返回当时的d。
伪代码

gcd(x,y)
	n = (x与y中较小的一个)
	for d从n到1
		if d是x和y的约数
			return d

这个算法虽然能正确地输出结果,但最坏情况下要进行n次除法,无法在规定时间内处理完较大的数据。

2. 欧几里得算法(Euclidean algorithm,辗转相除法)

定理:当x>=y时,gcd(x,y)等于gcd(y,x除以y之后的余数)。
运用这条定理,可以快速求解x与y最大公约数的算法。

3. 定理证明

设d为a和b的公约数,则有:(l,m为常数)
a = l d a=l * d ………………………………(1)
b = m d b=m * d ………………………………(2)
设r=a%b,则有:(k为常数)
a = k b + r a=k * b+r ……………………………(3)
将(1)(2)代入(3)得:
l d = k m d + r l * d=k*m*d+r
上式化简得:
r = ( l k m ) d r=(l-k*m)*d ……………………(4)
所以由(4)易得:d为r的约数。
又由(2)易得:d为b的约数。
综上两点,易得:d为b和r的公约数。
即证明:a与b的公约数,与,b和r(r=a%b)的公约数相等。
因此,a和b的公约数集合等于b和r的公约数集合,二者的最大公约数自然也相等。

4. 举例and时间复杂度

74与54的最大公约数:
g c d ( 74 , 54 ) = g c d ( 54 , 74 % 54 ) = g c d ( 54 , 20 ) = g c d ( 20 , 54 % 20 ) = g c d ( 20 , 14 ) = g c d ( 14 , 20 % 14 ) = g c d ( 14 , 6 ) = g c d ( 6 , 14 % 6 ) = g c d ( 6 , 2 ) = g c d ( 2 , 6 % 2 ) = g c d ( 2 , 0 ) = 2 gcd(74,54)\\=gcd(54,74\%54)=gcd(54,20)\\=gcd(20,54\%20)=gcd(20,14)\\=gcd(14,20\%14)=gcd(14,6)\\=gcd(6,14\%6)=gcd(6,2)\\=gcd(2,6\%2)=gcd(2,0)\\=2
时间复杂度大致为O(logb)。

5. 用递归函数求最大公约数
#include <iostream>
using namespace std;

int gcd(int x,int y)
{
	return y ? gcd(y,x%y) : x;
}

int main()
{
	int a,b;
	cin >> a >> b;
	cout << gcd(a,b) << endl;
}
6. 用循环求最大公约数
#include <iostream>
#include <algorithm>
using namespace std;

int gcd(int x,int y)
{
	int r;
	if(x<y) swap(x,y);//保证x>y
	while(y>0)
	{
		r = x%y;
		x = y;
		y = r;
	}
	return x;
}

int main()
{
	int a,b;
	cin >> a >> b;
	cout << gcd(a,b) << endl;
}

猜你喜欢

转载自blog.csdn.net/Sherry_Yue/article/details/88061791