参考 acwing 蓝桥杯辅导课
最大公约数
什么是最大公约数 ?
指两个或多个整数共有约数中最大的一个。也称最大公因数、最大公因子,a, b的最大公约数记为(a,b),同样的,a,b,c的最大 公约数记为(a,b,c),多个 整数的最大公约数也有同样的记号。求最大公约数有多种 方法,常见的有 质因数分解法、 短除法、 辗转相除法、 更相减损法。
欧几里得算法(辗转相除法)
- 理论基础 (a,b) = (b , a mod b); 最多只会执行
logn次 - 证明 左右两边的最大公约数是左右两边的一个约数
- 代换 a = kb + r; a mod b = r; 记 (b , a % b) 为 d。
d可以整除b 也可以整除 r 则 d 可以整除 a 0和 任意数的最大公约数都是任意数本身。- 代码
import java.util.*;
import java.io.*;
public class Main {
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int a = sc.nextInt();
int b = sc.nextInt();
System.out.println(gcd(a,b));
// System.out.println();
}
static int gcd(int a , int b) {
return b == 0 ? gcd(b , a % b) : a;
}
}
例题 等差数列
思路 : 等差数列表示为 a 、a + d 、 a + 2d ····· a + kd; 等差数列项数求法 : (an - a1) / d + 1; 使得 项数最小 则d要在公差里面最大 如何最大 、公差要取
最大公约数. 因为要包含 所有的数字 所以 最大的an和 最小的a1代入公式即可
代码
import java.util.*;
import java.io.*;
public class Main {
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();
int[] a = new int[n + 1];
int d = 0;
for (int i = 1; i <= n ; i ++) {
a[i] = sc.nextInt();
}
Arrays.sort(a);
for (int i = 1; i <= n ; i ++) d = gcd(d , a[i] - a[1]);
if (d == 0)
System.out.println(n);
else {
System.out.println((a[n] - a[1]) / d + 1);
}
}
static int gcd(int a , int b) {
return b == 0 ? a : gcd(b,a % b);
}
}