您的位置:首页 > 职场人生

创新工厂面试题详解:共打了多少鱼 -- 正解 递归求解法

2011-10-04 12:11 656 查看
今天看了一篇博文创新工场面试题详解题目:abcde五人打渔,打完睡觉,a先醒来,扔掉1条鱼,把剩下的均分成5分,拿一份走了;b再醒来,也扔掉1条,把剩下的均分成5份,拿一份走了;然后cde都按上面的方法取鱼。问他们一共打了多少条鱼?

许多小朋友都参与其中,挺有意思,我看了一下参与者的答案,发现大多都是采用循环遍历的方法,虽然能得到解,但不是正确的解题思路,这道题有简单的数学解: X = 5^5 - (5-1);

该题目可以推广到M个人,假设第一个人分鱼前有X1条鱼,第二个人分鱼前有X2条鱼.....第M个人分鱼前有Xm条鱼, 如果把鱼的数量增加M-1条,每个人都可以均分后拿掉自己的一份(不用再扔掉一条了),这样你可以导出:


X1 = M^M * Xm+1 / (M-1)^(M-1);

而 Xm+1 / (M-1)^(M-1) 的最小整数值为1,因此 X1 = M^M 了,再减去添加的M-1条,就得到了答案。

但作为编程题是在考你是否会使用递归算法.

根据题意可以得出如下公式:

X1- (X1-1)/M - 1 =X2 导出X1 =
(M*X2+M-1)/(M-1), 进一步可以推到出Xn = (M*Xn-1+M-1)/(M-1)。

跟据题意还可以知道,最后一个人分完后,鱼的数量是可以被M-1个人均分的 ,即Xm+1= (M-1)*k, k=1,2,3....为>0的整数。这样对于确定的M和k,Xm+1的值就是已知的,这样就可以用递归法求解该题了。

这样的解题效率是高的,对于M=5的情况,仅需255次循环就可以得到解 X1=3121.

为了增加趣味性,本程序在得到解后,将X1 ~ Xm 都输出出来了。

具体参见下面的代码,该程序采用递归算法,不太好理解,请大家认真阅读,递归程序是程序员的基本功啊。

不过这都是具体小玩意,小游戏而已,要想成为优秀的软件工作者,还是要多学习编码是设计方面的理论:参见/article/1447471.html/article/1447482.html

public class DisFish {
	static int M = 5;  //人的个数
	static int N = 2;  //希望得到几个结果
	static int result[] = new  int[M];
	public static void main(String[] args) throws Exception

	{		
		int n = 0;
		int k = 1;
		while (n < N) {
			int x1 = calculateX(2,k);   //x1 = f(x2) x1是x2的函数。
			if (x1>0) {
				n++;
				result[0]= x1;
				outRes(k);
			}
			k++;
		}
	}	
	/**
	 * 递归求解 Xm-1 =  (M*Xm+M-1)/(M-1) 
	 * @param m
	 * @param k  试算的正整数
	 * @return  返回-1 表示整数k试算失败,因为剩余的数量不能被M-1个人均分
	 */
	static int calculateX (int m,int k) {
		int xm = -1;
		if (m>M) {
			int x = (M-1)*k;
			xm = M*x / (M-1) + 1;
			return xm;
		}
		int xplus = calculateX(m+1,k);  //递归求解Xm+1
		if (xplus<0) return -1;
		int r = M*xplus%(M-1);
		if (r!=0) return -1;      //剩余的数量不能被M-1个人均分
		xm = M*xplus / (M-1) + 1;
		result[m-1] = xm;         //记录Xm 
		return xm;
	}
	
	static void outRes(int k){
		System.out.println(" k="+k);
		for (int i = 0; i < result.length; i++) {
			int p = i+1;
			System.out.print("X"+p+"="+result[i]+" ");
		}
		System.out.println();
	}
}


你也可以试着采用增加M-1条鱼后的递归公式进行编程求解,加深一下对递归算法的掌握。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: