习题4-7 最大公约数和最小公倍数 (15分)

习题4-7 最大公约数和最小公倍数 (15分)

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

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

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

输入样例:

511 292

输出样例:

73 2044

解题思路

最大公约数:指两个或多个整数共有约数中最大的一个。
最小公倍数:两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。

我一共尝试了3种方式,如下:

1、枚举法
高中数学(好像是高中?或者初中?)曾经讲过两个方法,辗转相除法和更相减损术。但是可能记不得这两个方法了,比如说我自己。那就只能直接粗暴根据定义解题,取个学术书面的名字就是枚举法,这里也介绍下枚举法。

枚举法:在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么这结论是可靠的,这种归纳方法叫做枚举法.枚举法是利用计算机运算速度快、精确度高的特点,对要解决问题的所有可能情况,一个不漏地进行检验,从中找出符合要求的答案。
特点:
1、得到的结果肯定是正确的;
2、可能做了很多的无用功,浪费了宝贵的时间,效率低下。
3、通常会涉及到求极值(如最大,最小,最重等)。
4、数据量大的话,可能会造成时间崩溃。

知道了枚举,这道题的解题步骤如下:

最大公约数:计算两个数中的较小数M的公约数,从大到小循环,得到的第一个公约数即为最大公约数。

最小公倍数:两个数中任意一个数M的n倍能够被另一个数N整除,即最小公倍数为M*n;

#include<stdio.h>
int main()
{
    int M,N,i,n=1;
    scanf("%d %d",&M,&N);
    if(M<N)
        i=M;
    else
        i=N;
    for(i;i>=1;i--)
    {
        if(M%i==0&&N%i==0)
        {
            printf("%d ",i);
            break;
        }

    }
    while(1)
    {
        if(n*M%N==0)
        {
            printf("%d",n*M);
            break;
        }
        n++;
    }
    return 0;
}

但是这种方法并不是最优的,效率不高,所以我又去查阅了更相减损术和辗转相除法求最大公约数,如下:
更相减损术算法:

1、任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行步骤2。
2、以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。则步骤1中约掉的若干个2与步骤2中等数的乘积就是所求的最大公约数。

#include<stdio.h>
#include<math.h>
int main()
{
    int M,N,n,temp,re;
    scanf("%d %d",&M,&N);
    while(M%2==0&&N%2==0){
        M/=2;
        N/=2;
        n++;
    }
    if(M<N){    
		temp=M;
		M=N;
		N=temp;
	}
    while(1){
        re=M-N;
        if(re==N)
            break;
        M=(re>N)?re:N;
        N=(re>N)?N:re;
    }
    printf("%d",(int)pow(2,n)*N);
    return 0;
}

辗转相除法

用较大数M除以较小数N,再将出现的余数re(第一余数)作为除数与N相除,再用出现的余数(第二余数)和第一余数相除,第一余数为为被除数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。

#include<stdio.h>
int main()
{
    int M,N,n,temp,re;
    scanf("%d %d",&M,&N);
	if(M<N){    
		temp=M;
		M=N;
		N=temp;
	}
    re=M%N;
    while(1){
        M=re;
        n=re;
        re=N%M;
        if(re==0)
            break;
        N=n;
    }
    printf("%d",M);
    return 0;
}

三种方法都编程实现了,测试可运行,使用debug看变量变化认识更深刻。

发布了21 篇原创文章 · 获赞 2 · 访问量 3368

猜你喜欢

转载自blog.csdn.net/weixin_44164333/article/details/104760461
今日推荐