比赛链接:
https://ac.nowcoder.com/acm/contest/6112
C.公因子
题目大意:
长为 \(n\) 的序列 \(a\),找到一个非负整数 \(x\),使得 \(gcd(a_1 + x, a_2 + x,..., a_n + x)\) 最大,输出最大的 \(gcd\) 以及使 \(gcd\) 最大的最小的 \(x\)。
思路:
因为 gcd(x, y) = gcd(x, y - x),所以求序列的最大的 gcd 其实就是求任意两个元素的差值的最大的 gcd。
所以我们可以对 \(a\) 进行一遍排序,然后做一个 差分,这些差值可以通过加减运算得到所有的差值。
这些元素的 gcd 一定 <= 其中的最小值,所以循环从最小值到 0 的每一个数,求出最大的 gcd,x 就是任意两个元素的差值 % gcd。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define all(x) (x).begin(), (x).end()
LL n;
vector <LL> num;
bool judge(LL x){
for (int i = 0; i < num.size(); ++ i)
if (num[i] % x != 0)
return false;
return true;
}
int main(){
cin >> n;
vector <LL> a(n);
for (int i = 0; i < n; ++ i)
scanf("%lld", &a[i]);
sort(all(a));
for (int i = 1; i < n; ++ i)
if (a[i] - a[i - 1] > 0)
num.pb(a[i] - a[i - 1]);
sort(all(num));
for (LL k = num[0]; k >= 0; -- k)
if (judge(k)){
cout << k << " " << abs(a[0]) % k << "\n";
break;
}
return 0;
}