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;
}

 

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