1. 程式人生 > >acm-最大公約數/最小公倍數 快速演算法

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;
}