PTA-C语言-最大公约数和最小公倍数(多解法,有扩展,附解析)

本题要求两个给定正整数的最大公约数和最小公倍数。

输入格式:

输入在一行中给出两个正整数M和N(≤1000)。

输出格式:

在一行中顺序输出M和N的最大公约数和最小公倍数,两数字间以1空格分隔。

输入样例:

511 292

输出样例:

73 2044

目录

PTA用直接解法

扩展:

更相减损法

辗转相除法:


开始解题:

最大公约数:如果数a能被数b整除,a就叫做b的倍数,b就叫做a的约数。即:

如果两个数a和b的最大公约数是c,那么c能整除a和b,且没有比c更大的数能整除a和b。

最小公倍数:最小公倍数是指两个或多个整数公有的倍数中最小的一个。即:

如果两个数a和b的最小公倍数是c,那么c是a和b的倍数,且没有比c更小的数是a和b的倍数。

PTA用直接解法

我脑海里的第一种基础解法思路:直接暴力求解,首先要知道,最小公约数一定比两个数都要小,所以先判断哪个数比较小,减少代码运算量。然后慢慢减小除数,直到算出第一个余数为0的结果,那么这个除数就是最大公约数。

而如何求最小公倍数呢?按照同样的思路,找出两个数里较大的数,慢慢增加这个数,直到这个数可以整除两个输入数。

#include
int main(){
	int m,n,i;
	int temp = 0;

	scanf("%d%d",&m,&n);
	temp=(mn)?m:n;//改变temp为较大的那个数,以下开始求最小公倍数
	while(1){
		if(temp%m==0&&temp%n==0)//条件与求最大公约数恰好相反
		break;
		temp++;
	}
	printf("%d",temp);
	return 0;
}

这个已经足以实现PTA通过了。接下来扩展讲一些知识点。

上面的代码过于直接,如果遇到一些特殊的数字的话,代码运算量比较大。

扩展:

更相减损法

更相减损法是一种用于计算两个整数最大公约数的算法。这种方法的基本思想是:不断用较大的数减去较小的数,然后用新的差值替换原来的较大数,继续这个过程,直到最后两个数相等。在这个相等的时候,两个数就是它们的最大公约数。
以下是代码实现

#include 

// 函数声明,用于计算两个数的最大公约数
int gcd(int a, int b) {
    // 如果b不为0,则继续用b和a的余数进行递归调用
    return b != 0 ? gcd(b, a % b) : a;
}

int main() {
    int num1, num2;
    
    // 用户输入两个整数
    printf("请输入两个整数:");
    scanf("%d %d", &num1, &num2);
    
    // 计算并输出最大公约数
    printf("最大公约数为:%d\n", gcd(num1, num2));
    
    return 0;
}

在这个代码中,gcd函数采用了递归的方式来不断地用较大的数减去较小的数,直到余数为0。这个时候,递归调用栈会回到最初的调用,此时的参数a就是两个数的最大公约数。
需要注意的是,更相减损法相比于其他算法如欧几里得算法,其效率并不是最高的,但是它的思想简单且易于理解。在实际应用中,如果对效率要求不是特别高,使用更相减损法是一个不错的选择

再再扩展一下,代码中提到的递归。

递归

指的是一个函数直接或间接地调用自身。

辗转相除法:

辗转相除法,又称欧几里得算法,是一种高效计算两个整数最大公约数(GCD)的方法。这种方法的基本思想是:用两个整数相除,然后用除数去除被除数,然后用新的被除数去除新的除数,重复这个过程,直到最后余数为0。最后一个非0余数就是两个数的最大公约数。

#include 

// 函数声明,用于计算两个数的最大公约数
int gcd(int a, int b) {
    // 辗转相除法的实现
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int main() {
    int num1, num2;
    
    // 用户输入两个整数
    printf("请输入两个整数:");
    scanf("%d %d", &num1, &num2);
    
    // 计算并输出最大公约数
    printf("最大公约数为:%d\n", gcd(num1, num2));
    
    return 0;
}

我比较习惯直接用,写着更加简单:

#include 
int main()
{
	int x = 0, y = 0;
	int tmp = 0;
	printf("请输入两个数字:");
	scanf("%d%d",&x,&y);
	while ( y != 0)//辗转相除法
	{
		tmp = x % y;//x变成两个数字中较大的数字
		x = y;
		y = tmp;//y被替换成第三个数字
	}
	printf("最大公约数是:%d\n", x);
	return 0;
}

你可能感兴趣的:(PTA-c语言实录,刷题日志,算法,数据结构,c语言)