猴子分桃 笔试题

海滩上有一堆桃子,五只猴子来分。
第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。
第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,
第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?

方法一:递归

#include <stdio.h>
#define N 4

int divide(int n,int m){
    if(n/N==0||n%N!=1){
        return 0;
    }
    if(m==1)
        return 1;
    return divide(n-n/N-1,m-1);
}
int main(int argc, char* argv[])
{
    int n;
    for(n=1;;n++){
        if(divide(n,N)){
            printf("%d",n);
            break;
        }
    }

    return 0;
}

方法二:遍历

方法2.1

#include <stdio.h>

int main(int argc, char* argv[])
{
    int monkey=1;//要分桃的猴子数
    int peaches=1;//总桃子数
    int peach=1;//每次分桃总数
    int m;
    scanf("%d",&m);

    while(monkey<=m){//循环给每个猴子分桃
        if(peach%m==1&&peach/m!=0){//成功分桃的情况
            peach=(peach/m)*(m-1);//可分桃数为当前总数的(m-1)/m
            monkey++;//继续给下一个猴子分桃
        }else{//分桃失败的情况
            peaches++;//可分桃数+1
            peach=peaches;
            monkey=1;
        }
    }
    printf("%d",peaches);
    return 0;
}

方法2.2

#include <stdio.h>
int monkeyPickPeach(int monkeyNum,int remain)//monkeyNum:猴子数,remain:每次分完剩余的桃子数
        {
            int resultNum = remain;
            int monkeyPicked = 0;
            int temp = 0;
            int tempSum = 0;
            bool isTemp = false;

            while (monkeyPicked < monkeyNum)
            {
                temp = resultNum / (monkeyNum-remain) + 1;

                if (!isTemp)
                {
                    tempSum = 0;
                }

                if ((resultNum+temp) % monkeyNum == remain && resultNum % (monkeyNum-remain) == 0)
                {
                    resultNum = resultNum + temp;
                    tempSum += temp;
                    monkeyPicked++;
                    isTemp = true;
                }
                else
                {
                    if (isTemp)
                    {
                        resultNum -= tempSum;
                    }

                    resultNum++;
                    monkeyPicked = 0;
                    isTemp = false;
                }
            }

            return resultNum;
        }
int main(int argc, char* argv[])
{
    printf("%d",monkeyPickPeach(4,1));
    return 0;
}

方法2.3

#include <stdio.h>
#define N 9
int main()
{
    int i,n,m;
    for(m=1;;m++)
    {
        n=m;
        for(i=1;i<N;i++)
        {
            if((n=N*n+1)%(N-1)) break;
            n=n/(N-1);
        }
        if(i==N) break;
    }
    printf("%d\n",N*n+1);
getchar();
}

方法三:公式,速度最快!
【引用:中国湖南祁阳陈小刚 http://www.doc88.com/p-9913644525470.html

sum=a*(a/m)^(n-1)-d*b/c
sum:分桃总数
n:分的次数(猴子个数)
a:每次分的份数
b:每次分a份后的余数
c:每次分a份后,拿走的份数
d:每次分a份后,拿走c份,剩下再分的份数
m:a与d的最大公约数
(b/c)不为正整数时,无解

(1)当m=1时,简化为:sum=a^n-d*b/c
(2)当m=c=1时,简化为:sum=a^n-d*b
(3)当m=c=b=1时,简化为:sum=a^n-d;(最简单的五猴分桃,总共分5次:n,每次分5份(五个猴子):a,每次多出1个:b,每次拿走1份:c,拿走后剩余4份:d,结果为5^5-4)

#include <stdio.h>


long power(int x,int y){
    int i;
    long result=1;
    for(i=0;i<y;i++)
    {
        result=result*x;
    }
    return result;
}
int main(int argc, char* argv[])
{
    int i;
    long m;
    scanf("%ld",&m);
    for(i=3;i<=m;i++){//3~m只猴
        printf("%ld\n",power(i,i)-(i-1));
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值