报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集
20周的完整安排请点击:20周计划
每周发1个博客,共20周。
在QQ群上交流答疑:

第16周: GCD和LCM
最大公约数(GCD)和最小公倍数(Least Common Multiple,LCM)研究整除的性质,非常古老,2000多年前就得到了很好的研究。由于简单易懂,有较广泛的应用,是竞赛中频繁出现的考点。
最大公约数有多种英文表述:Greatest Common Divisor(GCD)、Greatest Common Denominator、Greatest Common Factor(GCF)、Highest Common Factor (HCF)。
1. GCD
1.1 GCD概念
整数a和b的最大公约数是能同时整除a和b的最大整数,记为gcd(a, b)。
负整数也可以算gcd,不过由于-a的因子和a的因子相同,编码时只需要关注正整数的最大公约数。下面用c++函数std::__gcd(a, b)演示gcd的计算结果。
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << __gcd(45,9) <<"\n"; // 9
cout << __gcd(0,42) <<"\n"; // 42
cout << __gcd(42,0) <<"\n"; // 42
cout << __gcd(0,0) <<"\n"; // 0
cout << __gcd(20,15) <<"\n"; // 5
cout << __gcd(-20,15) <<"\n"; // -5
cout << __gcd(20,-15) <<"\n"; // 5
cout << __gcd(-20,-15)<<"\n"; // -5
cout << __gcd((long long)98938441343232,(long long)33422)<<"\n"; //2
}
Java没有自带GCD库函数。
Python自带的GCD函数,只返回正整数。
from math import *
print(gcd(45, 9)) # 9
print(gcd(0, 42)) # 42
print(gcd(42, 0)) # 42
print(gcd(0, 0)) # 0
print(gcd(20, 15)) # 5
print(gcd(-20, 15)) # 5
print(gcd(20, -15)) # 5
print(gcd(-20, -15)) # 5
print(gcd(98938441343232, 33422)) # 2
1.2 GCD性质
GCD有关的题目一般会考核GCD的性质。
(1)gcd(a, b) = gcd(a, a+b) = gcd(a, k·a+b)
(2)gcd(ka, kb) = k·gcd(a, b)
(3)多个整数的最大公约数:gcd(a, b, c) = gcd(gcd(a, b), c)。
(4)若gcd(a, b) = d,则gcd(a/d, b/d) = 1,即a/d与b/d互素。这个定理很重要。
(5)gcd(a+cb, b) = gcd(a, b)
1.2 GCD编码实现
编程时可以不用自己写GCD代码,而是直接使用c++函数std::__gcd(a, b)。如果自己编码也很简单,用欧几里得算法,又称为辗转相除法,即gcd(a, b) = gcd(b, a mod b)。
int gcd(int a, int b){
// 一般要求a>=0, b>0。若a=b=0,代码也正确,返回0
return b? gcd(b, a%b):a;
}
Java的gcd需要自己写。
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
System.out.println(gcd(45, 9)); // 9
System.out.println(gcd(0, 42)); // 42
System.out.println(gcd(42, 0)); // 42
System.out.println(gcd(0, 0)); // 0
System.out.println(gcd(20, 15)); // 5
System.out.println(gcd(-20, 15)); // -5
System.out.println(gcd(20, -15)); // 5
System.out.println(gcd(-20, -15)); // -5
System.out.println(gcd(new BigInteger("98938441343232"), new BigInteger("33422"))); // 2
}
public static long gcd(long a, long b) {
if (b == 0) return a;
return gcd(b, a % b);
}
public static BigInteger gcd(BigInteger a, BigInteger b) {
return a.gcd(b);
}
}
python。自己写gcd()函数,可能返回负数。
def gcd(a,b):
if b ==0:return a
else: return gcd(b,a%b)
print(gcd(45, 9)) # 9
print(gcd(0, 42)) # 42
print(gcd(42, 0)) # 42
print(gcd(0, 0)) # 0
print(gcd(20, 15)) # 5
print(gcd(-20, 15)) # 5
print(gcd(20, -15)) # -5
print(gcd(-20, -15)) # -5
print(gcd(98938441343232, 33422)) # 2
2. LCM
最小公倍数LCM(the Least Common Multiple)。a和b的最小公倍数lcm(a, b),从算术基本定理推理得到。
算术基本定理:任何大于1的正整数n都可以唯一分解为有限个素数的乘积: n = p 1 c 1 p 2 c 2 . . . p m c m n = p_1^{c1}p_2^{c2}...p_m^{cm} n=p1c1p2c2...pmcm,其中ci都是正整数, p i p_i pi都是素数且从小到大。
设: a = p 1 c 1 p 2 c 2 . . . p m c m , b = p 1 f 1 p 2 f 2 . . . p m f m a = p_1^{c1}p_2^{c2}...p_m^{cm},b = p_1^{f1}p_2^{f2}...p_m^{fm} a=p1

最低0.47元/天 解锁文章
1060





