• OC Round #9 简单的取石子游戏


    10165 : 简单的取石子游戏
    时间限制: 1000 MS 内存限制: 131072 KB 提交总数: 28 AC总数: 11
    问题描述
    现在有n堆石子,且已知每堆石子的数量,每次操作你可以从任一堆中取一颗石子放到另一堆中,问最少操作几次使得每一堆石子的数量均是某一个数的倍数。
    输入格式
    首先,输入一个n,代表有n堆石子。
    第二行有n个数,第i个数记为a[i],代表第i堆得初始石子数。
    【数据范围】
    1<=n<=100000,1<=a[i]<=100000。
    输出格式
    输出最少操作次数。
    样例输入
    样例输入1:
    5
    1 2 3 4 5
    样例输入2:
    2
    5 7
    样例输出
    样例输出1:
    2
    样例输出2:
    1

    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define N 100010
    using namespace std;
    typedef unsigned long long ull;
    int a[N],n,g[N],gp,c[N];
    ull sum,ans=1<<31,cnt;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
        for(ull x=2;x*x<=sum;x++)//分解质因数 
        while(sum%x==0)g[++gp]=x,sum/=x;
        if(sum>1)g[++gp]=sum;//手误,写成sum>0
        for(int i=1,w;i<=gp;i++)
        {
            sum=w=cnt=0;
            memset(c,0,sizeof c);
            for(int j=1,t;j<=n;j++)
            {
                t=a[j]%g[i];
                if(t>0)c[++w]=t,sum+=t;//需要花费步数来达到状态 
            }
            sort(c+1,c+w+1);
            for(int j=w;j;j--)//倒序,这样移动的步数会少 
            {
                cnt+=g[i]-c[j];
                sum-=g[i];//至多w堆石子加上这堆刚好都是b[i]的倍数 
                if(sum<=0)break;
            }
            ans=min(ans,cnt);
        }
        printf("%lld",ans);
        return 0;
    } 
    
    • 列表内容
  • 相关阅读:
    12.10
    4.06Android使用EditText小技巧汇总
    4.05
    4.04Android学习
    4.03Android学习
    4.02Android学习
    4.01Android学习
    3.31构建之法读后感3
    3.30Android学习
    3.29Android学习
  • 原文地址:https://www.cnblogs.com/wuzetian/p/9900409.html
Copyright © 2020-2023  润新知