洛谷 P1029 最大公约数和最小公倍数问题

洛谷 P1029 最大公约数和最小公倍数问题总结

一.求最大公约数的三种方法

(1)穷举法
(2)辗转相除法
(3)辗转相减法

1.穷举法

这是最容易想到,而且是最直接的方法。简言之,就是从1开始,到a,b中比较小的那个结束,看能不能同时被a, b整除(如果能即为公约数),这样一个循环下来一定可以找出GCD。

代码块

// 穷举法 
public static int gcd_enumeration(int a, int b){ 
    // 先找出a,b中小的那个 
    int smaller = a; 
    if (b < a) { 
       smaller = b; 
     } 
    int gcd = 1; 
    for (int i = 2; i <= smaller; i++) { 
        // 如果能同时被a和b除尽,则更新GCD 
        if ((a % i == 0) &;&; (b % i == 0)) { 
        gcd = i; 
        } 
    } 
   return gcd; 
} 

2.辗转相除法

(1)来自伟大数学家欧几里得的发现,gcd(a,b)=gcd(a,a mod b),这是辗转相除的基本理论。好了,有了理论基础,下面总结成算法步骤:

算法流程图

Created with Raphaël 2.1.2 a mod b a mod b 产生余数 r r==0(Yes or No?) (1)如果r==0,则a即为GCD (2)如果r!=0,a = b, b = r,返回步骤2 End yes no

代码块–递归部分

// 辗转相除法(递归写法) 
public static int gcd_division_recursive(int a, int b){ 
    if (b == 0) { 
       return a; 
     } 
    return gcd_division_recursive(b, a % b); 
} 

代码块–迭代部分

// 辗转相除法(迭代写法) 
public static int gcd_division_iteration(int a, int b){ 
    while(b != 0){// 为什么用b判断呢?因为b就是用来存a%b的,即上面算法步骤里的r的 
       int t = b; 
       b = a % b; 
      a = t; 
    } 
    return a; 
} 

3.辗转相减法

那就举个栗子瞧瞧看吧。

求32,12的最大公约数:
32 - 12 = 20 (20 > 12)
20 - 12 = 8 (8 < 12)
12 - 8 = 4 (4 < 8)
8 - 4 = 4 (4 == 4)
所以最大公约数是4.

代码块–递归部分

// 辗转相减法(递归写法) 
public static int gcd_substract_recursive(int a, int b){ 
     if(a == b) 
         return a; 
     return a > b ? gcd_substract_recursive(a - b, b) : gcd_substract_recursive(a, b-a);
} 

代码块–迭代部分

public static int gcd_substract_iteration(int a, int b){ 
       // 如果a,b不相等,则用大的数减去小的数,直到相等为止 
      while(a != b){ 
          if(a > b) 
             a = a - b; 
         else 
             b = b - a; 
      } 
     return a; 
} 

二.最大公约数GCD与最小公倍数LCM性质总结:

X,Y的乘积与其最大公约数与最小公倍数乘积相等。

三.针对题目

传送门

代码实现

#include<stdio.h>  
#include<iostream>  
using namespace std;  

int x, y;  

int gcd(int a, int b)  //(1)辗转除求最大公约数
{  
    return b == 0 ? a : gcd(b, a%b);  
}  

int main()  
{  
    //freopen("1.txt", "r", stdin);  
    cin >> x >> y;  
    int ans = 0;  
    for (int i = x; i <= y;i+=x)  
    {  

        for (int j = i; j <= y; j+=x)  
        {  
            int Gcd = gcd(i, j);  
            int Lcm = i*j / Gcd;  //(2)在性质总结出解释了
            if (Gcd == x&&Lcm == y) ans += 2;  
        }  
    }  
    cout << ans;  
    return 0;  
}  

猜你喜欢

转载自blog.csdn.net/m0_37630059/article/details/80712430
今日推荐