黑板上有 个正整数 ,再给定一个正整数 ,可进行操作如下:
- 选择一个黑板上的正整数 和两个满足 的正整数 ,删掉 ,在黑板上写上 和 ;
求最少进行多少次操作可以让黑板上的数相等,或报告无解。
,。
等号两边都有两个量不方便,注意到只要给每个 都减去 ,那么操作的限制就变成 ,且 。
那么无解当且仅当 不同号,即存在 满足 或 。
显然最后的数选择 最优,答案即为 。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int S=200005;
int n;
ll k,a[S];
inline ll gcd(ll x,ll y)
{
if(x==0||y==0) return x+y;
ll t=x%y;
while(t!=0) x=y,y=t,t=x%y;
return y;
}
inline void slove()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]-=k;
bool f=true;
for(int i=1;i<=n&&f;i++)
{
if(a[1]==0) f&=a[i]==0;
else if(a[1]>0) f&=a[i]>0;
else f&=a[i]<0;
}
if(!f) return puts("-1"),void();
if(a[1]==0) return puts("0"),void();
if(a[1]<0) for(int i=1;i<=n;i++) a[i]=-a[i];
ll m=0;
for(int i=1;i<=n;i++) m=gcd(m,a[i]);
ll ans=0;
for(int i=1;i<=n;i++) ans+=a[i]/m-1;
printf("%lld\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T-->0) slove();
return 0;
}