1. 程式人生 > 其它 >[Codeforces Round #748 (Div. 3)](https://codeforces.com/contest/1593) D2 Half of Same

[Codeforces Round #748 (Div. 3)](https://codeforces.com/contest/1593) D2 Half of Same

菜比要靠div3上藍,,,

題意

給出\(n\)個整數(\(n\)是偶數),構造一個正整數\(k\),每次操作你可以把某個數減\(k\),要求構造的\(k\)能夠使得至少一半的數最終相等,求最大的\(k\)。若\(k\)能無限大,輸出-1。

最多10組資料,\(4\le n \le 40\)\(-1e6\le a_i \le 1e6, \sum n \le 100\)

題解

如果沒有\(n/2\)的限制而是全部相等,只需要求出每個數和最小的數的差值求gcd即可。

考慮列舉前\(n/2\)小的數中的某一個作為最終要等於的數。處理出比它大的數和它的差值,分解因子並去重,記錄出現次數。隨後從最大的因子開始列舉,若某個因子出現了超過\(n/2\)

次,直接break,這個因子即為當前列舉的數的答案,複雜度通過去重保證。(因子個數一定不超過2e6)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 40 + 7;
#define ll long long
int n, m, tot, a[maxn];
int rd() {
	int s = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}
	return s * f;
}
map<int, int> fac[maxn], cnt;
int b[maxn];
int main() {
	int T = rd();
	while (T--) {
		m = 0;
		int ans = -1;
		n = rd();
		for (int i = 1; i <= n; i++) {
			a[i] = rd();
			fac[i].clear();
		}
		cnt.clear();
		sort(a+1, a+n+1);
		for (int i = 1; i <= n; i++) 
			cnt[a[i]]++;
		for (map<int, int> :: iterator it = cnt.begin(); it != cnt.end(); it++) {
			if ((*it).second >= n/2) {
				puts("-1");
				m = -114514;
				break;
			}
		}
		if (m == -114514) continue;
		m = 0;
		for (int i = 1; i <= n / 2 + 1; i++) {
			tot = m = 0;
			for (int j = i; j <= n; j++) {
				if (a[j] == a[i]) {
					m++;
					continue;
				}
				b[++tot] = a[j] - a[i];
			}
			for (int j = 1; j <= tot; j++) {
				for (int k = 1; k * k <= b[j]; k++) {
					if (b[j] % k == 0) {
						fac[i][k]++;
						if (k * k != b[j])
							fac[i][b[j]/k]++;
					}
				}
			}
			for (map<int, int> :: reverse_iterator rit = fac[i].rbegin(); rit != fac[i].rend(); rit++) {
				//printf("%d %d\n", (*rit).first, (*rit).second);
				if ((*rit).second >= n/2-m) {
					ans = max(ans, (*rit).first);
					//if (ans == 8) {
						//printf("i == %d\n", i);
						//break;
					//}
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}