acm-最大公约数/最小公倍数 快速算法

方法一:欧基里德算法:

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


你可能感兴趣的:(c++,算法)