1. 通过计算数组中两数的差值的g(最大公约数)来求数组中所有数加k后的公约数,因为数组中每个数加非负整数k不改变相邻两数的差值。设g为a,b的最大公约数,则a = g*m,b = g*n,a-b=g(m-n),显然g是a-b的公约数.
  2. 求公约数用欧几里得算法,迭代求出所有差值的最大公约数.
  3. k值计算:若存在k使得数组中所有数加k后的最大公约数为g,那么数组中的任意一个数arr[0](取第一个数)满足arr[0]+k为g的倍数。arr[0]与g取模,得到r为arr[0]模g的余数,k就等于g-r,为了确保最小k,k =(g-r)modg.
#include <stdio.h>
#include <math.h>
int gcd(int a, int b);
int main() {
    int n;
    scanf("%d", &n);
    int arr[n];
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    //计算差值的最大公约数
    int g_max = 0;//存储最大公约数,初始化为0,gcd(0,x)=x;
    for (int i = 1; i < n;i++) {
        int diff = abs(arr[i] - arr[i - 1]); //相邻差值
        g_max = gcd(g_max, diff);
    }
    //计算最小的非负k
    int r = arr[0] % g_max; // 第一个数模g_max的余数
    int min_k = (g_max - r) % g_max; // 保证k≥0且最小

    //输出结果(最大GCD + 最小k)
    printf("%d %d\n", g_max, min_k);
    return 0;
}
int gcd(int a, int b) {
    while (b != 0) { //当除数为0时退出
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;//返回被除数
}