最大公约数 GCD 和最小公倍数 LCM
GCD 即最大公约数Greatest Common Divisor。整数 a 和 b 的最大公约数是指能同时整除 a 和 b 的最大整数 编码时只需要考虑正整数的最大公约数
GCD的性质:
通常使用欧几里得算法(辗转相除法)来求GCD ,如下所示:(不论a,b谁大谁小全部适用 且a,b都为正整数)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println(gcd(a,b));
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
a 和 b 的最小公倍数 lcm(a, b),可以从算术基本定理推理得到。
有结论:lcm(a,b)*gcd(a,b)= a*b;
代码如下所示(稍微改动一下):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println((a*b)/gcd(a,b));
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
第一题 求最大公约数
很简单
样例输入
5
2 4
3 7
5 10
6 8
7 9
样例输出
2
1
5
2
1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
for (int i = 1; i <= N; i++) {
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println(gcd(a, b));
}
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
第二题 等差数列
样例输入
5
2 6 4 10 20
样例输出
10
import java.util.Arrays;
import java.util.Scanner;
public class Main {
private static int[] a;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = scanner.nextInt();
}
Arrays.sort(a);
int temp = a[1] - a[0];
for (int i = 1; i < N; i++) {
temp = gcd(temp, a[i] - a[i - 1]);
}
System.out.println((a[N-1]-a[0])/temp+1);
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
第三题 核桃的数量
这不就是就是求最小公倍数? 还有这么水的题,希望今年也这么简单??
样例输入
2 4 5
样例输出
20
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
int temp1 = (a * b) / gcd(a, b);
int temp2 = (temp1 * c) / gcd(temp1, c);
System.out.println(temp2);
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
第四题 斐波那契数列最大公约数
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger a = fb(2020);
BigInteger b = fb(520);
System.out.println(gcd(a,b));
}
private static BigInteger fb(int n) {
BigInteger[] a = new BigInteger[n+1];
a[1] = BigInteger.ONE;
a[2] = BigInteger.ONE;
for (int i = 3; i <= n; i++) {
a[i] = a[i-1].add(a[i-2]);
}
return a[n];
}
private static BigInteger gcd(BigInteger a, BigInteger b) {
if (b.equals(BigInteger.ZERO)) {
return a;
} else {
return gcd(b, a.remainder(b));
}
}
}
答案是6765 用java写大数真的很麻烦 可以用Python
第五题 最大最小公倍数
一定要挑出三个互质的数才能使最小公倍数 最大
样例输入
9
样例输出
504
较大的数输出的时候会有问题,绕不开的BigInteger
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
if (N % 2 == 1) {
System.out.println(N * (N - 1) * (N - 2));
} else {
if (N % 3 == 0) {
System.out.println((N - 1) * (N - 2) * (N - 3));
} else {
System.out.println(N * (N - 1) * (N - 3));
}
}
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
这样就没问题了
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
BigInteger n = new BigInteger(String.valueOf(N));
BigInteger n1 = new BigInteger(String.valueOf(N-1));
BigInteger n2 = new BigInteger(String.valueOf(N-2));
BigInteger n3 = new BigInteger(String.valueOf(N-3));
if (N % 2 == 1) {
System.out.println(n.multiply(n1).multiply(n2));
} else {
if (N % 3 == 0) {
System.out.println(n1.multiply(n2).multiply(n3));
} else {
System.out.println(n.multiply(n1).multiply(n3));
}
}
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
第六题 最大体积
样例输入
3
3
6
10
样例输出
17
import java.util.Scanner;
public class Main {
private static int[] a;
private static int[] dp;
private static int N;
private static int K = 2000;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
N = scanner.nextInt();
a = new int[N];
dp = new int[K];
for (int i = 0; i < N; i++) {
a[i] = scanner.nextInt();
}
dp[0] = 1;
if (gcdAll() == 1) {//与动态规划结合
for (int i = 0; i < N; i++) {
for (int j = a[i]; j < K; j++) {
if (dp[j - a[i]] == 1) {
dp[j] = 1;
}
}
}
} else {//不存在最大的体积
System.out.println(0);
}
for (int i = K-1; i >= 0; i--) {
if (dp[i] == 0) {
System.out.println(i);
break;
}
}
}
private static int gcdAll() {
int temp = a[0];
for (int i = 1; i < a.length; i++) {
temp = gcd(temp, a[i]);
}
return temp;
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
}
但是int数组申请的过大 肯定不会通过 太菜了,解决不了。
第七题 Hankson的趣味题
样例输入
2
41 1 96 288
95 1 37 1776
样例输出
6
2
import java.util.Scanner;
public class Main {
private static int n;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
for (int i = 0; i < n; i++) {
int a0 = scanner.nextInt();
int a1 = scanner.nextInt();
int b0 = scanner.nextInt();
int b1 = scanner.nextInt();
int ans = 0;
for (int j = 1; j * j <= b1; j++) {
if (j % a1 == 0 && b1 % j == 0) {
if (gcd(j, a0) == a1 && lcm(j, b0) == b1) {
ans++;
}
int k = b1 / j;
if (k == j) {
continue;
}
if (gcd(k, a0) == a1 && lcm(k, b0) == b1) {
ans++;
}
}
}
System.out.println(ans);
}
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
private static int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
}
第八题 最大比例
样例输入
3
1250 200 32
样例输出
25/4
import java.util.*;
public class Main {
static int N = 105;
static long[] x = new long[N], a = new long[N], b = new long[N];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
for (int i = 0; i < n; ++i)
x[i] = sc.nextLong();
Arrays.sort(x, 0, n);
int cnt = 0;
for (int i = 1; i < n; ++i) {
if (x[i] == x[i - 1]) continue;
long d = gcd(x[0], x[i]);
a[cnt] = x[i] / d;
b[cnt] = x[0] / d;
cnt++;
}
long up = a[0], down = b[0];
for (int i = 1; i < cnt; ++i) {
up = gcd_sub(up, a[i]);
down = gcd_sub(down, b[i]);
}
System.out.println(up + "/" + down);
}
}
private static long gcd(long a, long b) {
if (a == 0 || b == 0) return 0;
return a % b == 0 ? b : gcd(b, a % b);
}
public static long gcd_sub(long a, long b) {
if (a == b) return a;
return a > b ? gcd_sub(b, a / b) : gcd_sub(b, a);
}
}