1 条题解

  • 0
    @ 2026-9-30 12:33:32

    C++ :

    
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    using namespace std;
    /* 剩余 n-1 个数是原等差数列去掉一项。
       相邻间隔只能是 d 或 2d ⇒ gcd(所有间隔) ∈ {d, 2d} ⇒ d 只需试 {g, g/2} 两个值。
       对每个候选 d,枚举原等差数列首项在剩余序列中的下标 t(0 <= t <= n-1-span),
       补上唯一缺的那个位置即可。 */
    static long long y[1005];
    static vector<long long> cand;
    long long gcdll(long long a, long long b){ while(b){ long long t = a % b; a = b; b = t; } return a; }
    
    void try_d(int n, long long d){
        if(d <= 0) return;
        for(int i = 1; i < n - 1; i++)
            if((y[i] - y[0]) % d) return;              /* 必须整除 */
        long long span = (y[n - 2] - y[0]) / d;
        if(span > n - 1) return;
        for(long long t = 0; t + span <= n - 1; t++){
            long long first = y[0] - t * d;
            if(first < 1) break;                        /* 再往后首项更小 */
            bool seen[1005] = {false};
            for(int i = 0; i < n - 1; i++) seen[(int)(t + (y[i] - y[0]) / d)] = true;
            for(long long m = 0; m <= n - 1; m++)
                if(!seen[m]){ cand.push_back(first + m * d); break; }
        }
    }
    int main(){
        int n;
        if(scanf("%d", &n) != 1) return 0;
        for(int i = 0; i < n - 1; i++) scanf("%lld", &y[i]);
        sort(y, y + n - 1);
        if(n - 1 == 1){ printf("%lld\n", y[0] + 1); return 0; }
        long long g = 0;
        for(int i = 1; i < n - 1; i++) g = gcdll(g, y[i] - y[i - 1]);
        try_d(n, g);
        if(g % 2 == 0) try_d(n, g / 2);
        sort(cand.begin(), cand.end());
        cand.erase(unique(cand.begin(), cand.end()), cand.end());
        for(size_t i = 0; i < cand.size(); i++)
            printf("%lld%c", cand[i], i + 1 == cand.size() ? '\n' : ' ');
        return 0;
    }
    
    
    • 1

    信息

    ID
    2582
    时间
    1000ms
    内存
    256MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者