蓝桥杯 - 数论

211 阅读2分钟

参考 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;
    }
}

例题 等差数列

image.png

思路 : 等差数列表示为 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);
    }
}