更新
调用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;
}
601

被折叠的 条评论
为什么被折叠?



