1 条题解
-
0
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
- 上传者