A Simple Stone Game HDU - 6237

2018TYUT暑期ACM模拟赛(6)
A Simple Stone Game HDU - 6237
题意:给n堆石头,每次可以从一堆石头移动一个石头到另一堆。问最少移动多少次可以在找到一个因子是所有石头的因子。
思路:可以被所有堆石头正处,一定是可以被石头和给整除,寻找比和小的质因子。过一遍寻找。保存余数,将小堆石头加到大堆里面。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
//欧拉-质因子
typedef long long ll;
const int maxn=1e5+10;
ll a[maxn];
ll b[maxn];
ll prime[maxn+1],tot;
void getprime()
{
    memset(prime,0,sizeof(prime));
    for(int i=2;i<=maxn;i++)
    {
        if(!prime[i]) prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++)
        {
            prime[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
}

int  main()
{
    int t,n;getprime();
    while(~scanf("%d",&t))
    while(t--)
    {
        long long sum=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]),sum+=a[i];  ll ans=sum,x;//cout<<1<<endl;continue;
        int l=sqrt(sum)+1;
        for(int i=1;i<=prime[0]&&prime[i]<=l;i++)
        {
             x=prime[i];
            if(sum%x==0)
            {
                //cout<<"prime "<<prime[i]<<endl;
                ll tmp=0;
                int flag=0;
                long long s_sum=0;
                for(int j=0;j<n;j++)
                {
                    long long m=a[j]%x;
                    if(m)//
                    {
                        b[flag]=m;
                        s_sum+=b[flag++];
                    }
                }
                sort(b,b+flag);
                ll p=s_sum/x;//多少背
                for(int k=0;k<flag-p;k++)
                    tmp+=b[k];
                ans=min(tmp,ans);//cout<<tmp<<endl;
                //if(ans==0) break;
                //break;
            }
        }
         x=sum;
        ll tmp=0;
                int flag=0;
                long long s_sum=0;
                for(int j=0;j<n;j++)
                {
                    long long m=a[j]%x;
                    if(m)//
                    {
                        b[flag]=m;
                        s_sum+=b[flag++];
                    }
                }
                sort(b,b+flag);
                for(int k=0;k<flag-1;k++)
                    tmp+=b[k];
                ans=min(tmp,ans);//cout<<tmp<<endl;
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/miranda_ymz/article/details/81168057