强盗分赃问题

描述

有天夜里5个强盗A、B、C、D、E抢到一大堆金币(金币个数不超过n个,n<=100000000),可是怎么也无法平均分成5份,吵吵嚷嚷……

吵累了,只好先睡觉,准备第二天再分。

夜深了,一个强盗A偷偷爬起来,先拿了一个金币私下放自己口袋藏好,再将金币分为5等份,将自己的那一份再私藏好就去睡觉了。

随着第二个强盗B也爬起来,也是私拿了一个金币再分5等份,也私藏起自己那份就睡觉去了。

后来的三个强盗C、D、E也都是这样办的。

问最初有多少个金币?(最初的金币个数有多种可能,请输出n以内所有可能,从小到大排列)



输入格式

输入一个数,n。
请输出金币数不超过n的可能的初始金币个数。


输出格式

初始金币个数的多种可能(初始金币个数小于等于n)。

请输出不超过n的“所有的”可能,从小到大排列出,中间空格相连。

分析
1.直接判断:使用函数判断每个数是否符合(理解简单),代码如下:
int count=0;
bool func(int num){
     int tmp=num-1;         //每个强盗先私藏一个
     while(tmp%5==0&&count<5){                  
                              count++;
                              func(tmp/5*4);   //递归,下一个强盗
                              }
     if(count==5)
        return true;   //符合,返回true
     else 
     return false;  //否则,返回false
}

2.数学方法推断:
 假设到第五个强盗E时,平均每个强盗得到x个金币,则:
第五个强盗E藏掉一个金币后剩 5x 个 
第四个强盗D藏掉一个金币后剩 5(5x+1)/4 = 25x/4+5/4 
第三个强盗C藏掉一个金币后剩 5(25x/4+5/4+1)/4 = 125x/16+45/16 
第二个强盗B藏掉一个金币后剩 5(125x/16+45/16+1)/4 = 625x/64+305/64 
第一个强盗A藏掉一个金币后剩 5(625x/64+305/64+1)/4 = 3125x/256+1845/256 
原来共有金币 3125x/256+1845/256+1 = 3125x/256+2101/256 = (12x+8)+53(x+1)/256 
所以,能使得53(x+1)/256为整数就可以了。
代码如下:
#include<iostream>
#include<stdlib.h>
using namespace std;

int main(){
    int n;
    cin >>n;
    if(n<3121)
       cout <<"impossible";  //由上面推断知,最小满足是3121
    
    
    int sum=0;
    for(int x=255;x>0;x++){    //有上面推断知,最小满足X=255
        sum=(12*x+8)+53*(x+1)/256;
        if(sum>n) break;
        if((53*(x+1)%256)==0)
          cout <<sum<<" ";
        }
   
    return 0;
}



你可能感兴趣的:(算法,递归,数学,C语言)