zoukankan      html  css  js  c++  java
  • 求最小公倍数,最大公约数

    题目

    正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。

    输入描述:

    输入两个正整数A和B。

    输出描述:

    输出A和B的最小公倍数。

    示例

    输入

    5 7
    

    输出

    35
    

    解析

    最小公倍数:2个整数公有的倍数叫这2个数的公倍数,其中最小的公倍数叫最小公倍数。
    最小公倍数求法:
    最小公倍数 = 两数乘积 ÷ 最大公约数

    求最大公约数的算法:

    1. 辗转相除法
    2. 相减法
    3. 穷举法

    辗转相除法
    辗转相除法,也叫欧几里德算法。
    两个整数a、b(a >= b),如果a mod b = 0,那么a和b的最大公约数是b。

    原理:
    设整数a、b最大公约数为z,a >= b,那么a mod z = 0, b mod z = 0, <=> a = kz,b = tz,其中k,t为整数。
    设a对b的余数为c,即c = a mod b <=> a = bj + c ,j是整数
    => a - bj = c
    => kz - tzj = c
    => (k - tj)z = c
    => c也能被z整除
    因此,a、b的最大公约数,等价于求a、b余数c(a mod b)和b的最大公约数。而c <= min(a, b),因此可以不断往复迭代缩小求公约数的范围,直到余数c为0,此时的b值即为所求。

    /**
    最大公约数
    辗转相除法
    c = a % b, a > b
    a = b
    b = c
    直到c = 0,b即为最大公约数
    gcd: greatest common divisor
    */
    int gcd(int a, int b) {
        int c;
        if (a < b) swap(a, b);
        
        c = a % b;
        while (c != 0) {
            a = b;
            b = c;
            c = a % b;
        }
        
        return b;
    }
    

    递归形式

    int gcd(int a, int b) {
      return b == 0? a : gcd(b, a % b);
    }
    

    辗转相减法
    辗转相减法,也叫尼考曼彻斯发。
    有2个整数a、b,

    1. 如果a > b,则 a = a - b;
    2. 如果a < b,则 b = b - a;
    3. 如果a = b,则a或b即为两数的最大公约数;
    4. 如果a ≠ b,则回到步骤1执行;

    如求27、15最大公约数过程:
    a = 27, b = 15

    1. ∵a = 27 > b = 15 ∴a = a - b = 12;
    2. ∵a = 12 < b = 15 ∴b = b - a = 3;
    3. ∵a = 12 > b = 3 ∴a = a - b = 9;
    4. ∵a = 9 > b = 3 ∴a = a - b = 6;
    5. ∵a = 6 > b = 3 ∴a = a - b = 3;
    6. ∵a = 3 == b ∴a=3是原数对27、15的最大公约数;
    int gcd(int a, int b) {
      if (a == 0 || b == 0) return 0;
    
      while (a != b) {
        if (a > b) a -= b;
        else b -= a;
      }
    
      return a;
    }
    

    最小公倍数

    最小公倍数 = a * b / gcd(a, b), 其中,a、b不能为0,gcd(a, b)是a和b的最大公约数
    当a或b为0时,最小公倍数=0

    /*
    最小公倍数 = a * b / 最大公约数
    lcm: least common multiple
    */
    int lcm(int a, int b) {
        if (b == 0) return b;
        else return a * b / gcd(a, b);
    }
    
    int main() {
        int a, b;
        
        cin >> a >> b;
        if (a <= 0 || b <= 0) {
            cerr << "invalid input" << endl;
            return 0;
        }
        
        cout << lcm(a, b) << endl;
        
        return 0;
    }
    

    参考

    求最小公倍数 | 牛客网 华为机试

    C语言求最小公倍数和最大公约数三种算法(经典) | 博客园

  • 相关阅读:
    Educational Codeforces Round 6
    Codeforces Round #373 (Div. 2)
    尺取法
    Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2)
    逆元(数论倒数)
    最大公约数gcd,最小公倍数lcm,扩展欧几里得
    hdu 6395 Sequence (分段矩阵快速幂)
    快速幂
    hdu 6432 Cyclic
    hdu 6397 charactor encoding
  • 原文地址:https://www.cnblogs.com/fortunely/p/14700606.html
Copyright © 2011-2022 走看看