算法:最大公约数

更新

调用GCD函数无需保证a > b,因为当a < b时,GCD(a, b)返回GCD(b, a % b)GCD(b, a)

扩展

输出分数p/q时,考虑0、负数和整数的特殊情况。

模板

#include "GCD.h"

/**
  * @brief: output the fraction p/q
  * @param p: numerator of fraction
  * @param q: denominator of fraction
  */
void FRAC(int p, int q) {
  if (p == 0) {  // p/q = 0
    printf("0");
    return;
  }
  int tag = 1;
  if (p < 0) {
    p = -p; 
    tag *= -1;
  }
  if (q < 0) {
    q = -q; 
    tag *= -1;
  }
  int tmp = GCD(p, q);
  p /= tmp, q /= tmp;
  if (tag == -1) printf("-");  // p/q < 0
  if (q == 1) printf("%d", p);  // integer
  else printf("%d/%d", p, q);  // fraction
}

很快ACM校集训队要选拔了,想学一波算法,顺便记下模板。

最大公约数

功能

输入两个数ab,输出ab的最大公约数。

最大公约数:

  1. 既可以整除a,也可以整除b的数,组成集合C
  2. 集合C中的最大元素,即最大公约数

思路

辗转相除法:

  1. ab中较大值max除以较小值min
  2. 若整除,则结果为min
  3. 若不整除,则令ab分别等于min和余数mod,递归步骤1
    可以证明,ab的最大公约数等于minmod的最大公约数。

时间复杂度

O(log n),考虑斐波那契数列,对数列相邻两项使用最大公约数算法为最坏情况,而斐波那契数列通项为指数数量级。

扩展

最大公约数与最小公倍数的乘积等于a * b

最小公倍数:

  1. 既可以被a整除,也可以被b整除的数,组成集合D
  2. 集合D中的最小元素,即最小公倍数

模板

/**
  * @param a: number A
  * @param b: number B
  * @return: the greatest common divisor of A and B
  */
int GCD(int a, int b) {
  return b == 0 ? a : GCD(b, a % b);
}

测试

#include "GCD.h"
#include <cstdio>
#include <cstdlib>
#include <ctime>

const int MAX = 100;
const int SIZE = 10;

int main() {
  int a, b, ans;
  
  srand(time(NULL));
  for (int i = 0; i < SIZE; ++i) {
    a = rand() % MAX + 1;
    b = rand() % MAX + 1;
    ans = GCD(a, b);
    printf("a = %3d, b = %3d, ans = %3d\n", a, b, ans);
  }

  return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值