更新
調用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校集訓隊要選拔了,想學一波算法,順便記下模板。
最大公約數
功能
輸入兩個數a
和b
,輸出a
和b
的最大公約數。
最大公約數:
- 既可以整除
a
,也可以整除b
的數,組成集合C
- 集合
C
中的最大元素,即最大公約數
思路
輾轉相除法:
- 用
a
和b
中較大值max
除以較小值min
- 若整除,則結果爲
min
- 若不整除,則令
a
和b
分別等於min
和餘數mod
,遞歸步驟1
可以證明,a
和b
的最大公約數等於min
和mod
的最大公約數。
時間複雜度
O(log n)
,考慮斐波那契數列,對數列相鄰兩項使用最大公約數算法爲最壞情況,而斐波那契數列通項爲指數數量級。
擴展
最大公約數與最小公倍數的乘積等於a * b
。
最小公倍數:
- 既可以被
a
整除,也可以被b
整除的數,組成集合D
- 集合
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;
}