代码源每日一题
Polycarp 有一个长度为 nn 的数组 a1,a2,...,ana1,a2,...,an(nn 是偶数)。Polycarp 还得到了一个正整数 kk,他开始对数组 aa 做如下操作:选择一个下标 i (1≤i≤n)i (1≤i≤n) 使 aiai 减去 kk。
在 Polycarp 进行若干次操作后(可能 00 次),数组 aa 中的所有数都变成相同的了。请你找到最大的符合要求的 kk,如果 kk 可以为任意大,请输出 −1−1。
输入格式
第一行一个整数 tt,表示测试单元的个数。
接下来每个测试单元有两行。第一行包含一个偶数 nn。第二行包含 n 个整数 a1,a2,...,ana1,a2,...,an。
输出格式
对于每个测试单元输出单独一行一个整数 k (k≥1)k (k≥1) —— Polycarp 能用来对数组进行操作的最大的数,或者 −1−1 —— 如果 kk 能任意大的话。
样例输入
3
6
1 5 3 1 1 5
8
-1 0 1 -1 0 1 -1 0
4
100 -1000 -1000 -1000
样例输出
2
1
1100
数据规模
所有数据保证 1≤t≤101≤t≤10,4≤n≤404≤n≤40(nn 是偶数),−106≤ai≤106−106≤ai≤106,并且 n 的总和不超过100。
思路:这个题其实就是找出除了最小值之外,其余值到最小值的距离的最大公约数,求全部的公约数:就是将数组全部遍历一遍即可,得到最后的gcd即可。当数组中的数全部相同时gcd为0。
关于无数次gcd更新的解释(题目:Not Adding——无数次更新的gcd):无数次更新其实只用看最后一次的结果就行,无数次更新并且往里添数时需要注意的是不能遍历数组的长度n,而要直接遍历数据的大小范围,确定的倍数之间的最大公约数,公约数与倍数之间的最大公约数仍是这个最大公约数,大的数可以代替小的最大公约数!
完整代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9+7;
const int N=1e6+10;
int a[N];
void solve()
{
int n;
cin>>n;
int minn=1e7;
for(int i=1;i<=n;i++)
{
cin>>a[i];
minn=min(minn,a[i]);
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(a[i]==minn)continue;
ans=__gcd(ans,a[i]-minn);
}
if(ans)
{
cout<<ans<<endl;
}
else
{
cout<<"-1"<<endl;
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin>>t;
while(t--)
{
solve();
}
return 0;
}