Half of Same

传送门

题意

略....

思路

对于两个数字 \(a, b\) ,假设二者可以通过减去一些 \(k\),使其变得相同,那么 \(a - xk = b - yk\)

\(a \% k = b \% k\),并且 \(k\) 最大为 \(max(a,b) - min(a, b)\) \((a-b=(x-y) \times k , k \le a - b)\)

因此我们可以通过枚举任意两个数字的差值的所有因子进行判断是否合法来更新最大值

CODE
/********************
Author:  Nanfeng1997
Contest: Codeforces - Codeforces Round #748 (Div. 3)
URL:     https://codeforces.ml/contest/1593/problem/D2
When:    2022-03-15 19:54:20

Memory:  256MB
Time:    1000ms
********************/
#include  <bits/stdc++.h>
using namespace std;
using LL = long long;

void solve() {
  int n; cin >> n;
  map<int, int> cnt;
  vector<int> a(n); for(int &x: a) cin >> x, cnt[x] ++;
  for(auto &[k, v]: cnt) if(v >= n / 2) {
    cout << "-1\n";
    return;
  }
  
  int ans = 0;
  auto chk = [&] (int x) -> bool {
    map<int, int> mp; 
    for(int i = 0; i < n; i ++ ) mp[((a[i] % x) + x) % x] ++;
    for(auto &[k, v]: mp) if(v >= n / 2) return true;
    return false;
  };
  sort(a.begin(), a.end());
  for(int i = 0; i < n; i ++ ) 
    for(int j = i + 1; j < n; j ++ ) {
      int res = a[j] - a[i];
      for(int k = 1; k * k <= res; k ++ ) {
        if(res % k) continue;
        if(chk(k)) ans = max(ans, k);
        if(chk(res / k)) ans = max(ans, res / k);
      }
    }
    cout << ans << "\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int T; cin >> T;
  while(T --) solve();

  return 0;
}

posted @ 2022-03-15 20:31  ccz9729  阅读(41)  评论(0编辑  收藏  举报