zoukankan      html  css  js  c++  java
  • 最大公约数(GCD)

    题目描述

    求整数a、b的最大公约数。

    题目分析

    所谓求整数a、b的最大公约数,就是求同时满足a%c=0、b%c=0的最大正整数c,即求能够同时整除a和b的最大正整数c。

    暴力枚举

    若a、b均不为0,则依次遍历不大于a(或b)的所有正整数,依次试验它是否同时满足两式,并在所有满足两式的正整数中挑选最大的那个即为所求;

    若a、b其中有一个为0,那么最大公约数即为a、b中非零的那个;

    若a、b均为0,则最大公约数不存在(任意数均可同时整除它们)。

    说明:当a和b数值较大时(如100000000),该算法耗时较多。

    欧几里德算法(又称辗转相除法)

    若a、b全为0,则它们的最大公约数不存在;若a、b其中之一为0,则它们的最大公约数为非0的那个;若a、b都不为0,则使新a=b;新b=a%b然后重复该过程。

    说明:证明过程见最下边。

    代码实现

     
    递归实现
    #include <iostream>
    using namespace std;
    
    int gcd(int a, int b)
    {
    	if (a == 0 && b == 0)
    		return -1; // 不存在
    
    	// a、b为负数时,先求绝对值,再求最大公约数
    	if (a < 0)
    		a = -a;
    	if (b < 0)
    		b = -b;
    
    	if (b == 0)
    		return a;
    	return gcd(b, a%b);
    }
    
    int main()
    {
    	int m, n;
    	while (cin >> m >> n)
    	{
    		cout << gcd(m, n) << endl;
    	}
    	return 0;
    }
    循环实现
    #include <iostream>
    using namespace std;
    
    int gcd(int a, int b)
    {
    	if (a == 0 && b == 0)
    		return -1; // 不存在
    
    	// a、b为负数时,先求绝对值,再求最大公约数
    	if (a < 0)
    		a = -a;
    	if (b < 0)
    		b = -b;
    
    	while (b != 0)
    	{
    		int t = a%b;
    		a = b;
    		b = t;
    	}
    	return a;
    }
    
    int main()
    {
    	int m, n;
    	while (cin >> m >> n)
    	{
    		cout << gcd(m, n) << endl;
    	}
    	return 0;
    }
    

    欧几里德算法证明

    1> 证明a、b的公约数同时也是b、a mod b 的公约数

    image

    2> 证明若g是a、b的最大公约数,它同样也是b、a mod b 的最大公约数

    我们假设g是a、b的最大公约数,但它并不是b、a mod b 的最大公约数,

    image

  • 相关阅读:
    Linux下面编译安装ffmpeg
    Fidder简单使用方法(HTTPS抓取和url替换)
    关于一下个阶段的计划
    JAVA的随机的字符串的封装(基本上够用了)
    Shell Script中的间接变量引用
    进程概念
    int main(int argc, char *argv[])的解读
    存储数组数据到SharedPreferences
    C语言中的基本声明
    C中关于指针数组的用法
  • 原文地址:https://www.cnblogs.com/xwz0528/p/4816861.html
Copyright © 2011-2022 走看看