[Codeforces Round #748 (Div. 3)](https://codeforces.com/contest/1593) D2 Half of Same
阿新 • • 發佈:2021-10-17
菜比要靠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\)
#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; }