因为要计算最小移动次数,所以可以考虑贪心进行计算,同时可以看出的是x是a中所有元素的因子,考虑这点进行计算,因为要将所有数凑成有公因子x,所以考虑对sum进行素因子分解进行计算,因为x一定能分解成素因子,将a中每一个元素对素因子取模,计算移动次数,从大到小采用贪心的计算方法。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=1e5+10;
#define INF 0x3f3f3f3f3f3f3f3f
typedef long long ll;
int a[MAXN],b[MAXN];
ll prime[MAXN];
int num,n;
bool cmp(ll a,ll b){
return a>b;
}
ll cal(ll mi){
int i;
ll tot=0;
for(i=0;i<n;i++){
b[i]=a[i]%mi;
tot+=b[i];
}
sort(b,b+n,cmp);
i=0;
ll ans=0;
while(tot&&i<n){
ans+=mi-b[i];
tot-=mi;
i++;
}
return ans;
}
void sushu(ll sum){
num=0;
for(ll i=2;i<=sqrt(sum);i++){
if(sum%i==0) prime[num++]=i;
while(sum%i==0) sum/=i;
}
prime[num++]=sum;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
ll sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
sushu(sum);
ll ans=INF;
for(int i=0;i<num;i++){
if(sum%prime[i]==0){
ll tmp=cal(prime[i]);
ans=min(ans,tmp);
}
}
printf("%lld\n",ans);
}
return 0;
}