河南萌新联赛2026第(一)场:河南工业大学B题题解
侧边栏壁纸
  • 累计撰写 4 篇文章
  • 累计收到 2 条评论

河南萌新联赛2026第(一)场:河南工业大学B题题解

llwqs
2026-07-27 / 0 评论 / 3 阅读 / 正在检测是否收录...

题目核心思路解析
这里是题目链接
1. 操作的本质与等差数列的性质
题目允许我们对数组中的元素进行任意次“加 $x$”或“减 $x$”的操作。这意味着,最终数组中的每个元素 $a_i$ 都可以变成 $a_i + k \cdot x$($k$ 为任意整数)。
换句话说,每个元素在模 $x$ 意义下的余数是不会改变的。

假设我们最终将数组变成了一个公差为 $D$ 的等差数列,那么对于任意相邻的两个元素,它们的差值在模 $x$ 意义下必须等于 $D$。
即:$a_{i+1} - a_i \equiv D \pmod x$。

2. 推导关键约束条件
既然所有的相邻差值 $a_{i+1} - a_i$ 在模 $x$ 意义下都等于 $D$,那么任意两个相邻差值在模 $x$ 意义下必须相等。
即:$(a_{i+1} - a_i) \equiv (a_{j+1} - a_j) \pmod x$。

将其转化为整除关系,即:$x$ 必须能整除任意两个相邻差值的差。
即:$x \mid ((a_{i+1} - a_i) - (a_{j+1} - a_j))$。

为了让 $x$ 尽可能大,我们需要找到所有“相邻差值的差”的最大公约数(GCD)。

完整代码

#include<bits/stdc++.h> 
using namespace std;
long long my_gcd(long long a, long long b) {
    a = abs(a);
    b = abs(b);
    while (b != 0) {
        a %= b;
        swap(a, b);
    }
    return a;
}

int main() {
    int n;
    if (!(cin >> n)) return 0;
    
    vector<long long> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    bool is_arithmetic = true;
    if (n >= 2) {
        long long diff = a[1] - a[0];
        for (int i = 2; i < n; ++i) {
            if (a[i] - a[i-1] != diff) {
                is_arithmetic = false;
                break;
            }
        }
    }
    if (is_arithmetic) {
        cout << -1 << endl;
        return 0;
    }
    long long base_diff = a[1] - a[0];
    long long gcd_val = 0;
    
    for (int i = 2; i < n; ++i) {
        long long current_diff = a[i] - a[i-1];
        long long val = current_diff - base_diff;
        gcd_val = my_gcd(gcd_val, val);
    }
    cout << gcd_val << endl;
    
    return 0;
}
1

评论 (0)

取消