算法:最大公約數

更新

調用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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章