HDU 6237 A Simple Stone Game

HDU 6237 A Simple Stone Game

题目大意:

有n堆石子,每一堆都有ai块。

每次可以任意将一个石子从一堆移动到另外一堆,代价为1.

让最后的每一堆石子都是一个质数的倍数(默认0为任何数的倍数)

求最小代价?

思路:

因为如果有一个数x,最后每一堆石子的个数都是它的倍数,那么所有石子的和一定也是x的倍数。

求每一堆石子的和sum,然后将其分解质因数。

然后对每一个质因数进行验证。

怎么验证呢?贪心即可。对每组数取一个x的模。取模之后的数从小到大排序,将少的移动到多的上面。如果再一次到达x,那么最大的堆变成零,多出来的往次大堆上放。

#include<bits/stdc++.h>
#define MAXN 100010
#define ll long long
using namespace std;
int n,T,maxx,cnt,cnt2;
ll sum;
int a[MAXN],prime[MAXN],cur[MAXN],not_prime[MAXN],Prime[MAXN];
inline void pre_solve(){
	not_prime[1]=1;
	for(int i=2;i<=100000;i++){
		if(not_prime[i]==0){
			prime[++cnt]=i;
		}
		for(int j=1;j<=cnt&&prime[j]*i<=100000;j++){
			not_prime[prime[j]*i]=1;
			if(i%prime[j]==0) break;
		}
	}
}
inline int ll calc(ll x){
    ll cur_ans=0;
    memcpy(cur,a,sizeof(int)*(n+1));
    for(int i=1;i<=n;i++) cur[i]%=x;
    sort(&cur[1],&cur[n+1]);
    int l=1,r=n;
    while(l<r){
        while(cur[l]%x==0) l++;
        while(cur[r]%x==0) r--;
        int cur_sum=cur[l]%x;
        cur_ans+=cur_sum;
        while((cur[r]+cur_sum)>x){
            cur_sum-=x-cur[r];
            r--;
        }
        cur[r]+=cur_sum;
        l++;
    }
    return cur_ans;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&T);
    pre_solve();
    while(T--){
        sum=0,maxx=0,cnt2=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sum+=a[i];
            maxx=max(maxx,a[i]);
        }
        long long ans=sum-maxx;
        int pre=2;
        for(int i=pre;i<=(int)sqrt(sum);i++){
            if(not_prime[i]==true||sum%i!=0) continue;
            else{
                Prime[++cnt2]=i;
                pre=i;
                while(sum%i==0) sum/=i;
            }
        }
        // 
        // for(int i=1;i<=cnt2;i++) printf("%d ",Prime[i]); puts("");
        for(int i=1;i<=cnt2;i++){
            ans=min(ans,calc(Prime[i]));
        }
        if(sum!=1) ans=min(ans,calc(sum));
        printf("%lld
",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/fengxunling/p/13667805.html