HDU 6237.A Simple Stone Game 贪心 ,素数 2017ccpc哈尔滨

题意:让你转移n堆石子,每次最多转移1个,问最少的次数使得每堆石子的数量是x的倍数

解:

考虑,最后x一定也是sum的质因子。

对所有a[i]求余, 那么大的余数+上一部分就能变成mod 小的余数分到别人身上 自己变成0

只从将大的变成mod来分析不会出错,

因为从小的考虑的话,可能还是多个小的才凑出来,那么计算会不那么简洁

#include<bits/stdc++.h>
#define en '\n'
#define ll long long
const ll maxn=1e5+10;
using namespace std;
ll n,a[maxn];
ll sm=0;
const ll inf=0x3f3f3f3f3f3f3f3f;
#define all(x) x.begin(),x.end()
ll rd(){ll t;scanf("%lld",&t);return t;}
vector<ll>prime,vec;
signed main()
{
    #ifdef swt
    freopen("input2.txt","r",stdin);
    #endif
    int T;
    cin>>T;
    while(T--){
    cin>>n;
    sm=0;
    for(ll i=1;i<=n;i++){
        a[i]=rd();sm+=a[i];
    }
    #define pb push_back
    prime.clear();
    for(ll i=2;i*i<=sm;i++){
        if(sm%i==0){
            prime.pb(i);
            while(sm%i==0)sm/=i;
        }
    }
    if(sm>1){prime.pb(sm);}
    sort(all(prime));
    ll ans=inf;
    for(ll i=0;i<prime.size();i++){
        ll x=prime[i];vec.clear();
        ll sum=0;
        for(ll j=1;j<=n;j++){
            if(a[j]%x==0)continue;
            vec.pb(a[j]%x);
            sum+=(a[j]%x);
        }
        sort(all(vec));
        ll tem=0;
        for(ll j=0;;++j)
        {
            tem+=vec[j];
            sum-=prime[i];
            if(sum<=0)break;
        }
        ans=min(ans,tem);
    }
    cout<<ans<<en;
    }
    return  0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章