蓝桥杯 Day15 java组 初等数论

最大公约数 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);
    }
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值