D2. Half of Same
分析 (solution one):
-
暴力枚举所有可能约数即可
约数最大为 2 e 6 2e6 2e6, O ( n ∗ 2 e 6 ) O(n*2e6) O(n∗2e6),刚好卡过去
-
由于是多组数据,要多次清空数组,这里有个优化的小技巧,详见代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5;
int a[105];
int vis[N],cnt[N];
signed main()
{
int T;
cin>>T;
int cas=0;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i], a[i]+=1e6;
int ans=0;
for(int i=N;i>0;i--)
{
cas++;
int mx=0;
for(int j=1;j<=n;j++)
{
int x=a[j]%i;
if(vis[x]<cas) vis[x]=cas,cnt[x]=0; // 优化小技巧
if(mx<++cnt[x]) mx=cnt[x];
}
if(2*mx>=n)
{
ans=i;
break;
}
}
if(ans==N) puts("-1");
else cout<<ans<<endl;
}
}
分析 (solution two):
-
用 s e t set set 记录所有可能出现的约数( s e t set set 乱搞~)
-
将所有的约数从大到小遍历
再由 D 1 D1 D1 (见下文) 当中讲过的,以一个数为基准,判断所有数与这个数的差值是否能被约数整除
若满足条件的数超过 n 2 \frac{n}{2} 2n, 输出答案即可
#include <bits/stdc++.h>
using namespace std;
int a[105];
set <int, greater<int> > sd,sp;
signed main()
{
int T;
cin>>T;
int cas=0;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int cnt=1,sum=1;
for(int i=2;i<=n;i++)
{
if(a[i]!=a[i-1]) sum=max(sum,cnt), cnt=1;
else cnt++;
}
sum=max(sum,cnt);
if(sum*2>=n) { puts("-1"); continue; }
sd.clear(); sp.clear();
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
sd.insert(a[j]-a[i]);
}
}
for(auto v : sd)
{
for(int j=1;j*j<=v;j++)
{
if(v%j==0)
{
sp.insert(j); sp.insert(v/j);
}
}
}
int ans=1,fg=0;
for(auto v : sp)
{
for(int i=1;i<=n/2+1 && !fg;i++)
{
int t=1;
for(int j=i+1;j<=n;j++)
{
if((a[j]-a[i])%v==0) t++;
}
if(t*2>=n)
{
ans=v;
fg=1;
}
}
if(fg) break;
}
cout<<ans<<endl;
}
}
D1. All are Same
分析:
- 要求一个最大的 k k k 使得序列中的所有数加上若干个 k k k 之后相等
- 计算所有差值的 g c d gcd gcd 即可
- 但是没必要 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1) 个差值,以一个数为基准,计算所有数与这个数的差值即可
#include <bits/stdc++.h>
using namespace std;
const int N=105;
int gcd(int a,int b) { return b ? gcd(b,a%b) : a; }
int a[N];
signed main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int ans=0;
for(int i=2;i<=n;i++)
{
int d=a[i]-a[i-1]; // a[i]-a[1]也行
if(d==0) continue;
ans=gcd(d,ans);
}
if(!ans) puts("-1");
else cout<<ans<<endl;
}
}