zoukankan      html  css  js  c++  java
  • HDU

    传送门:https://vjudge.net/problem/HDU-6237

    思路:

      因为要求完成一系列操作以后每一堆石子的个数都是一个数(大于1)的倍数,因此可以推出,这些石子数的总和也一定是这个数的倍数,所以,我们要求的这个数,一定是石子数总和的一个质因子(因为凑素因子的公因子比凑素因子的倍数为素因子更加容易),所以直接枚举和的所有质因子,然后让所有石子对于这个这个质因子取余,重新得到一个序列,我们接下来需要做的就是将得到的这个新序列凑成这个质因子的倍数的序列(因为石子数的总和是该质因子的倍数,所以这个操作一定能实现),接下来,将新序列从小到大排序,并求出它的总和为sum2,因为要求操作数最少,即要求移动的石子数最少,所以从后往前遍历,每次的操作数就是当前这个数与素因子的差值,同时sum2也应该减去这个素因子,代表有一个素因子已经凑好了。枚举每一个素因子,求最小值即可。(注意long long).

    具体细节见代码。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    #include <iostream>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+200;
    LL num[maxn];
    LL len ;
    LL solve(LL sum)
    {
        vector<LL> dic;
        dic.clear();
        for(LL i = 2;i*i<=sum;i++)
        {
            if(sum%i==0)
            {
                dic.push_back(i);
                while(sum%i==0)
                    sum/=i;
            }
        }
        if(sum>1) dic.push_back(sum);
        //sort(dic.begin(),dic.end());
        LL ans = 1e17;
        for(int i = 0;i<dic.size();i++)
        {
            LL sum1 = 0,ans1 = 0;
            vector<LL> s;
            s.clear();
            for(int j= 0 ;j<len;j++)
            {
                if(num[j]%dic[i]!=0)
                {
                    s.push_back(num[j]%dic[i]);
                    sum1 += num[j]%dic[i];
                }
            }
            sort(s.begin(),s.end());
            for(int j = s.size()-1;j>=0;j--)
            {
                ans1+=(dic[i]-s[j]);
                sum1-=dic[i];
                if(sum1<=0) break;
            }
            ans = min(ans,ans1);
        }
        return ans ;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d",&n);
            len = n;
            LL sum = 0;
            for(int i = 0;i<n;i++)
            {
                scanf("%lld",&num[i]);
                sum+=num[i];
            }
            LL ans = solve(sum);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Django基础二之URL路由系统
    Django基础一之web框架的本质
    HTTP协议超级详解
    动态规划-背包问题
    java 中对象比较大小
    排序算法
    泛型
    打jar包和使用jar包
    Mongodb中Sharding集群
    linux时间同步,ntpd、ntpdate
  • 原文地址:https://www.cnblogs.com/baihualiaoluan/p/11238465.html
Copyright © 2011-2022 走看看