“小乐乐与欧几里得”的思考,C语言实现最大公因数和最小公倍数的三种方式

一、引例 - 牛客网OJ题

 为了更好地说明这个问题,我们以一道牛客网的题目作引例。题目链接贴在这里

小乐乐与欧几里得_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/da13e0cf321e4df9acd0fdf0a433cbb0?tpId=290&tqId=632016&ru=%2Fpractice%2Ffcd30aac9c4f4028b23919a0c649824d&qru=%2Fta%2Fbeginner-programmers%2Fquestion-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E8%25AF%25AD%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D290

题干如下: 

f647e840702e441990d70bf9251976dc.png

当我们提到最大公因数和最小公倍数时,不得不提及的一个重要数学概念就是公倍数和公因数,那么究竟什么是公倍数与公因数呢?今天就让我们揭开它神秘的面纱,看一看他的庐山真面目,来浅显的了解一下他们的概念。

二、公因数与公倍数的概念

公因数

简介

公因数,亦称“公约数”。它是一个能同时整除若干整数的整数 [1]。如果一个整数同时是几个整数的因数,称这个整数为它们的“公因数”;公因数中最大的称为最大公因数。

对任意的若干个正整数,1总是它们的公因数。

释义

给定若干个整数,如果有一个(些)数是它们共同的因数,那么这个(些)数就叫做它们的公因数。而全部公因数中最大的那个,称为这些整数的最大公因数

公约数与公倍数相反,就是既是A的约数同时也是B的约数的数,12和15的公约数有1,3,最大公约数就是3。再举个例子,30和40,它们的公约数有1,2,5,10,最大公约数是10。

公因数,又称公约数。在数论的叙述中,如果n和d都是整数,而且存在某个整数c,使得n = cd,就说d是n的一个因数,或说n是d的一个倍数,记作d|n(读作d整除n)。如果d|a且d|b,我们就称d是a和b的一个公因数。根据裴蜀定理,对每一对整数a,b,都有一个公因数d,使得d = ax+by,其中x和y是某些整数,并且a和b的每一个公因数都能整除这个d。于是d的绝对值叫做最大公因数。

求几个整数的最大公因数,只要把它们的所有共有的质因数连乘,所得的积就是它们的最大公因数

详情见:

 公因数_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E5%85%AC%E5%9B%A0%E6%95%B0?fromModule=lemma_search-box

裴属定理

在数论中,裴蜀定理是一个关于最大公约数(或最大公约式)的定理,裴蜀定理得名于法国数学家艾蒂安·裴蜀。

裴蜀定理(或贝祖定理)得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。

换句话说,裴蜀定理表明,如果a和b的最大公约数为d,则存在整数x和y,使得ax + by = d,同时对于任意整数k,ax + by = kd的解也存在。这个定理的一个重要应用是判断两个整数是否互质,即它们的最大公约数是否为1。

证明及详情见:

裴蜀定理_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E8%A3%B4%E8%9C%80%E5%AE%9A%E7%90%86/0

公倍数

简介

公倍数(common multiple)是指在两个或两个以上的自然数中,如果它们有相同的倍数,这些倍数就是它们的公倍数。公倍数中最小的,就称为这些整数最小公倍数(lowest common multiple) [1]。

举例

A和B A/B=C 如果A能被B整除,则A为B和C的公倍数 两个数A和B,它们的公倍数就是既是A的倍数又是B的倍数的数,即能同时被A、B整除的数  比如说:12和15,它们的公倍数是60,120,180,等等  在这些公倍数中最小的那一个就叫最小公倍数,就是60。

详情见

公倍数_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E5%85%AC%E5%80%8D%E6%95%B0/1064191

三、最大公因数的实现

穷举法

当我们想到求解m,n的最大公因数时,脑海中第一个浮现的念头就是利用for循环条件m与n同时除以 同一个数 i ,然后让i++,直到求出等于两数其一为止。因为这种方法几乎将所有的元素都取了一遍因此叫做穷举法。即,for(i=1;i<n;i++);

#include <stdio.h>
int main()
{
	int m=0,n=0;
	int i=1,ret=0;
	scanf("%d%d",&m,&n);
                           //除数不能为0,因此循环从i=1开始。
	for(i=1;i<=m;i++)
	{                           //当m<n时,因为最大公因数一定小于等于m,所以i<=m条件成立;
                                //当m>n时,且当i>n时,n%i一定不成立,因数不会赋值给ret
                                //因此,m与n相对大小,对程序的相对运行没有影响。
		if((m%i==0)&&(n%i==0))     
			ret=i;            //将因数赋值给ret
	}
	printf("%d",ret);
	return 0;
}

 辗转相除法

由上述提到的裴属定理可知,辗转相除法最大的用途就是用来求两个数的最大公约数。

辗转相除法又叫做欧几里得法,两个整数的最大公约数等于其中较小的数和两数的差的最大公约数。

详情见:

辗转相除法介绍 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/324578532

#include<stdio.h>
int main()
{
    int m,n,r;
	scanf("%d%d",&m,&n);
	while(r=m%n)        
	{
		m=n;
		n=r;
	}
	printf("最大公因数为:%d\n",n);	
	return 0; 
} 

更相减损术

更相减损之术,又叫尼考曼彻斯法,其思想最早见于西汉《九章算术》中,“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之”。

它的白话译文是:如果需要对分数进行约分,那么)可以折半的话,就折半(也就是用2来约分)。如果不可以折半的话,那么就比较分母和分子的大小,用大数减去小数,互相减来减去,一直到减数与差相等为止,用这个相等的数字来约分。

详情见:

更相减损术_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E6%9B%B4%E7%9B%B8%E5%87%8F%E6%8D%9F%E6%9C%AF/449183

#include <stdio.h>
int main()
{
	int m=0,n=0;
	scanf("%d%d",&m,&n);
	while(m!=n)           //循环相减直到m=n
	{
		if(m>n)   //保证较大数减去较小数,结果不是负数。
			m-=n;
		else
			n-=m;
	}
	printf("%d",m);//结果m=n,因此不必担心m,n位置互换
	return 0;
}

四、最小公倍数的实现

穷举法

常言道,万事不决,量子力学。而对于公倍数而言,我们可以万事不决,利用穷举法,利用循环全部寻找出来。

#include <stdio.h>
int main()
{
	int n,m,i,ret;
	scanf("%d%d",&m,&n);
	for(i=m;i<=m*n;i++)//最小公倍数的最坏情况是两数互为质数,因此循环到m*n结束。
	{
	    if(i%m==0&&i%n==0)
		{
			ret=i;
			break;       //找到最小公倍数后跳出循环;
		}
	}
	printf("最小公倍数是:%d\n",ret);
	return 0;
}

辗转相除法

我们知道:当利用短除法求出m,n最大公因数之后,两数互质,因而将两数相乘再乘以最大公因数就是最小公倍数。

【动画笔记】辗转相除法——求最大公约数和最小公倍数 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/508687942

#include<stdio.h>
int main()
{
	int m,n,r;
	int  com=0;
	scanf("%d%d",&m,&n);
	int i=m,j=n;//保留m,n的数值
	while(r=m%n)        
	{
		m=n;
		n=r;    //求出最大公因数n
	}
	com=i*j/n;
	printf("最小公倍数为:%d\n",com);	
	return 0; 
}

这种方法的好处是他几乎能将所有能求出最大公因数的方法为雏形,演化成为最小公倍数的解法,几乎是“代码界的缝合怪”。

叠乘法

已知两个数的公倍数一定与这两个数存在倍数关系,那么求解最小公倍数我们就可以将其中一个数依次扩大1倍、2倍、3倍……直到出现第一个扩大n倍的数可以同时整除这两个数,这个数就是最小公倍数。

#include<stdio.h>
int main()
{
	int m,n;
	int i=1;
	int  com=0;
	scanf("%d%d",&m,&n);
	while(m*i%n!=0)
	{
		i++;
	}
	
	com=m*i;
	printf("最小公倍数为:%d\n",com);	
	return 0; 
}

  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值