解题—求两数的最大公约数与最小公倍数 #辗转相除法

文章目录

前言

一、最大公约数

方法一:硬解

方法二:辗转相除法

1、图形理解:

 2、公式理解:

二、最小公倍数

方法一:硬解

方法二:巧解

总结


前言

路漫漫其修远兮,吾将上下而求索。


一、最大公约数

假设输入的两个值为m 与 n ;

方法一:硬解

总所周知,最大公约数一定小于等于输入两个值中的最小值;

倘若 n > m ,那么这两个数的最大公约数一定小于等于 n  ; 而最大公约数同时满足被 n 与 m 整除;

故而其代码如下:

#include<stdio.h>

int main()
{
	int n = 0;
	int m = 0;
	while (scanf("%d %d", &n, &m)!= EOF)
	{
		int max = n > m ? n : m;
		int min = n < m ? n : m;
		//最大公约数
		int gcd = min;
		while (1)
		{
			if (n % gcd == 0 && m % gcd == 0)
				break;

			gcd--;
		}
		printf("%d\n", gcd);
	}
	return 0;
}

方法二:辗转相除法

辗转相除法又称为欧几里得算法,用于计算两个非负整数m,n的最大公约数。

1、图形理解:

例如:需求 624 与 1404 的最大公约数;如下图所示:

将数据 624 与 1404 转换成一个矩形而要被一个最大的正方形填充;

在上图中可以清楚地发现,将短边在长边中组成正方形,不看正方形部分于是乎就又形成了一个新的长方形,又在这个新长方形中用短边组成长方形来填充……直到所有面积均被划分地正方形填充,那么此正方形便是填充这个长方形的最大正方形;(看下图可能会明显一点)

转换成数学语言就是将余数除以被除数(余数一定小于被除数)得到的余数再除以上一个式子的被除数;

体现在上图中就是不停地在长边中划分短边的正方形……一直重复直到长边完全被短边划分;那么此时的短边正方形便是填充原矩形的最大正方形;

那么体现成数学公式便为:

 2、公式理解:

默认 a,b 为整数,而求a ,b 的最大公约数;

(a,b)-->求 a,b 的最大公约数(a,b)

本质原理:a/b=q…r

如果有两个整数a,b 便会存在唯一的一个整数q和r,满足式子 a/b=q...r

经过上面图形的启发,我们可得知:(a,b)=(b,r)

如何验证这个公式呢?
由a/b=q…r,可得a=b*q+r;以及r=a-b*q;

  • 假设(a,b) = d1; 则可以得到 a= d1*m,b=d1*n,其中(n,m)=1,即m与n 互质;存在n与m均属于整数那么可知:r=d1*m -di*n*q= d1(m-ng);

  • 假设 (b,r) =d2;则可以得到 b=d2*m,r=d2*n,其中(m,n)=1,存在n与m均属于整数;那么可知:a=d2*m*q+d2*n= d2*(m*q+n)


而又存在(a , b, c, d)=((a,b),c, d);所以(a, b,r )=((a,b),r)=( a,(b,r));

  • ((a,b),r)=(d1,r)=(d1,d1(m-ng))=d1;因为m,n,g必为整数,所以 m-ng 必为整数,故而其最大公约数为d1;
  • (a,(b,r))=(a,d2)=(d2*(m*g+n),d2)= d2 ;

然而a br这三个整数只存在唯一的最大公约数,故而 d1=d2;

即(a,b)=(b,r)得以验证

即存在:

代码如下:

//辗转相除法
#include<stdio.h>

int main()
{
	int n = 0;
	int m = 0;
	int gcd = 0;
	while (scanf("%d %d", &m, &n) != EOF)//多组输入
	{
		while (m%n)//
		{
			int c = m % n;
			m = n;//被除数当作除数
			n = c;//余数当作被除数
		}
		//当循环停止时,即计算下去无余数时此时的被除数便为最大公约数
		gcd = n;

		printf("最大公约数为%d\n", gcd);

	}

	return 0;
}

代码运行结果如下:

二、最小公倍数

假设输入的两个值为m 与 n ;

方法一:硬解

可知,最小公倍数的一定小于等于两数之积而大于等于两数中的较大值;

代码如下:

//最大公倍数
#include<stdio.h>

int main()
{
	int m = 0;
	int n = 0;
	while (scanf("%d %d", &m, &n) != EOF)
	{
		int lcm = n > m ? n : m;
		while (1)
		{
			if (lcm % n == 0 && lcm % m == 0)
				break;
			lcm++;
		}
		printf("最小公倍数为:%d\n", lcm);
	}

	return 0;
}

代码运行结果如下:

方法二:巧解

在得知最大公约数的情况下满足 : m*n = 最大公约数*最小公倍数;

为什么呢?

如下图:

假设 m = 76x , n = 27x ;那么可知 m*b = 76* x * 27 *x;

而最小公约数为 x ,最大公倍数为 76*27*x; --> 所以得知 m*n = 最大公约数*最小公倍数;

代码如下:

#include<stdio.h>

int main()
{
	int n = 0;
	int m = 0;
	int gcd = 0;
	int lcm = 0;
	while (scanf("%d %d", &m, &n) != EOF)
	{
		//最大公约数
		int i = m;//保护 m,n
		int j = n;
		while (i % j)
		{
			int ret = i % j;
			i = j;
			j = ret;
		}
		gcd = j;
		//最小公倍数
		lcm = (n / gcd) * (m / gcd) * gcd;

		printf("最小公倍数为:%d", lcm);
	}
	return 0;
}

代码运行结果如下:


总结

假设需求m,n 的最大公约数与最小公倍数;

最大公约数:硬解;辗转相除法

最小公倍数:硬解;巧解(辗转相除法+原理:m*n = 最大公约数*最小公倍数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值