比赛链接:

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;
}
posted on 2022-03-05 11:48  Hamine  阅读(8)  评论(0编辑  收藏  举报