石子游戏

本文介绍了一款石子游戏的最少移动次数计算方法。通过分析得出,最小质因子的余数系最小,只需处理分解出的第一个质因子。具体实现上采用贪心+模拟的方法,先找出所有质因子,再通过模拟计算出最少移动次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

在Bob学会怎样玩Nim Game之后,他打算尝试另一款看起来更为简单的石子游戏

这个游戏是这样子玩的:一共有一个玩家,且一开始有N堆石头,第i堆石头有ai个石子。玩家每次只能移动一个石子从一堆到另一堆。在每次移动结束后,如果存在一个整数x(x>1)满足任意一堆的当前石子数bi都是x的倍数,那么游戏结束。

现在你需要帮助Bob计算出为了结束这个无聊的游戏,他最少需要移动的次数。特别的, 0是任何正整数的倍数。

Analysis

考试时候没来得及分析就打了个爆搜,现在发现其实是一道贪心+模拟..

很显然,x一定是石子和的质因子。wts告诉我,最小质因子的余数系最小,所以只需要处理分解出来的第一个质因子即可。

接下来就是模拟了..为了让数据更加清晰,可以把每个石子都mod一下最小质因子,得出来的都是0~x-1的数,显然要把它们合并成若干个x,所以只需要计算出x的个数,然后从大到小填充即可。

Code

#include <bits/stdc++.h>
int n,s[110],ans;
std::vector <int > prime;
void factor(int x){
    for(int i=2;i<=x;i++){
        if(!(x%i))prime.push_back(i);
        while(!(x%i))x/=i;
    }
}
void move(int x){
    int mo[110];
    memset(mo,0,sizeof(mo));
    int sum=0;
    for(int i=1;i<=n;i++)
        mo[i]=s[i]%x,sum+=mo[i]; 
    std::sort(mo+1,mo+n+1);
    int k=sum/x;
    for(int i=n;i>=n-k+1;i--)
        ans+=x-mo[i];
}
int main(){
    scanf("%d",&n);
    int sum=0;
    for(int i=1;i<=n;i++)
        scanf("%d",&s[i]),sum+=s[i];
    factor(sum);
    move(prime[0]);
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/qswx/p/9644073.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值