hdu 6237 A Simple Stone Game (求素因子+贪心)

因为要计算最小移动次数,所以可以考虑贪心进行计算,同时可以看出的是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;
}



猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/81290687