算法编程:共打了多少鱼?

来源:互联网 发布:在淘宝买好还是天猫好 编辑:程序博客网 时间:2024/05/11 09:00

        今日闲来无事看到某帖子上的编程面试题,拿来练练手吧。

abcde五人打渔,打完睡觉,a先醒来,扔掉1条鱼,把剩下的分成5分,拿一份走了;b再醒来,也扔掉1条,把剩下的分成5份,拿一份走了;然后cde都按上面的方法取鱼。问他们一共打了多少条鱼,写程序和算法共打了多少条鱼的结果有很多。(提示:最少打的鱼的结果是3121条鱼)


        这个可以将问题倒置思考。最开始有n条鱼,x个人逐个过来放上眼前鱼总数的 n/4 + 1 条鱼,那么第x个人放完后 有多少鱼?

        通过高中那时的推导法(名字还给老师了)推出了公式:第n-1个人 与 他拿走后余下鱼的数量 f(n)的关系【这里之所以用n-1是因为 推导出的函数是等比数列,令其为n次方比较好看 ^ ^,而且很巧合的是编码时候这个n-1也很合适,因为第0个是不需要满足条件的^ ^ 】

经过一番分析核对,公式如此: 【最后一位拿走后余下 a 条鱼,共 n 个人拿过鱼,0<=k<=n】

         f(n)   =   (a*  5^n  + 4*  5^(n-1)  + ... 4^k  * 5^(n - k) + 4^n-1  *  5 +  4^n)  /  4^n

                 =  (5/4) ^n   *  (a+4)   -    4

         f(n) ~ p(n-1)  

       根据题目要求:f(n)必须为整数,则需要调整a以得出f(n)吧。


代码如下:


#include "stdio.h"#include <math.h>#include <ctype.h>/* 核心算法 */int Fish_amount_speed(int p_num){int n = p_num ;int i_up = 0;int i_up_1 = pow(5.0,n);int i_up_2 = pow(4,(n+1));int i_down = pow(4.0,n);for (int i = 1;1;i++)//i 已经是p0值,所以要计算的 人数里面 共有 p_num -1个,正好是结果需要值{i_up = (i+4)*i_up_1 + i_up_2;if(i_up%i_down == 0) return (i_up/i_down);} return 0;}int main(){int people_max = 5;int fish_get_last = 1;int fish_cnt_min = Fish_amount_speed(people_max);//计算printf("最少是%d条\n",fish_cnt_min);for (int i = 0;i < people_max;i++){printf("第%d个人拿走了%d条\n",i+1,((fish_cnt_min-1)/5));fish_cnt_min = (fish_cnt_min-1)/5 * 4;}return 0;}

结果输出:

 
最少是3129条
第1个人拿走了   625条
第2个人拿走了   499条
第3个人拿走了   399条
第4个人拿走了   319条
第5个人拿走了   255条
press any key to continue


题目来自:

创新工厂面试题详解:共打了多少鱼