acm-最大公約數/最小公倍數 快速算法

方法一:歐基裏德算法:

#include <iostream>
#include <fstream>
using namespace std;
int gcd(int, int);
int main(int agrc, char*agvc[])
{
	int m, n;
	ifstream cin("a.txt");
	while (cin >>m >>n)
	{
		cout << gcd(m, n) << endl;
		
	}
	system("pause");
	return 0;

}
int gcd(int a, int b)
{
	while (a != b)
	{
	
		if (a > b) a -= b;
		else b -= a;
		
	}
	return a;
	
}

方法二更快:化歸思想

/*tein 算法求最大公約數,和歐基裏德算法相比,效果更好:
 主要思想如下: 化歸思想
 
  
 1.m爲奇數時:
    (1)n也爲奇數:gcd(m,n) = gcd((m+n)/2,(m-n)/2) ;
    (2)n爲偶數:  gcd(m,n) = gcd(m,n/2) ;
  
 2.m爲偶數時:
   (1) n也爲偶數:gcd(m,n) = gcd(m/2,n/2);
   (2) n爲奇數:  gcd(m,n) = gcd(m/2,n);

 3.m == n 時,gcd(m,n) = m 退出

*/
#include <cstdio>
#include <iostream>
using namespace std;
int stein_gcd(int m, int n)
{
	int temp, total = 0;
	if (m < n)
	{
		temp = m;
		m = n;
		n = temp;
	}

	if (n == 0)
		return 0;

	while (m != n)
	{
		if (m & 1) /* 如果m 爲奇數, 因爲奇數的後面總有一個1,所以可以通過與1且一下來判斷是否是偶數*/
		{
			if (n & 1) /* m,n都爲奇數*/
			{
				temp = m;
				m = (m + n) >> 1;
				n = (temp - n) >> 1;
			}
			else
			{
				n >>= 1;
			}
		}
		else /* m爲偶數 */
		{
			if (n & 1) /*n 爲奇數*/
			{
				m >>= 1; /*由於在這個過程中,m可能小於n ,所以要判斷一下*/
				if (m < n)
				{
					temp = m;
					m = n;
					n = temp;
				}
			}
			else
			{
				m >>= 1;
				n >>= 1;
				total++; /*記錄縮小的倍數*/
			}
		}
	}
	m <<= total; /*還原大小*/

	return m;
}
int main(int agrc ,char* agrv[])
{
	int m, n, max = 0;
	while (cin >> m >> n)
		cout << stein_gcd(m, n) << endl;
	//printf("%d\n", max);
	return 0;
}


發佈了54 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章