您的位置:首页 > 编程语言

【编程马拉松】【005-猴子分桃】

2016-05-29 13:08 246 查看

【编程马拉松算法目录>>>】

【005-猴子分桃】【工程下载>>>】

1 题目描述

  老猴子辛苦了一辈子,给那群小猴子们留下了一笔巨大的财富——一大堆桃子。老猴子决定把这些桃子分给小猴子。

  第一个猴子来了,它把桃子分成五堆,五堆一样多,但还多出一个。它把剩下的一个留给老猴子,自己拿走其中的一堆。

  第二个猴子来了,它把桃子分成五堆,五堆一样多,但又多出一个。它把多出的一个留给老猴子,自己拿走其中的一堆。

  后来的小猴子都如此照办。最后剩下的桃子全部留给老猴子。

  这里有n只小猴子,请你写个程序计算一下在开始时至少有多少个桃子,以及最后老猴子最少能得到几个桃子。

1.1 输入描述:

  输入包括多组测试数据。

  每组测试数据包括一个整数n(1≤n≤20)。

  输入以0结束,该行不做处理。

1.2 输出描述:

  每组测试数据对应一行输出。

  包括两个整数a,b。

  分别代表开始时最小需要的桃子数,和结束后老猴子最少能得到的桃子数。

1.3 输入例子:

5
1
0


1.4 输出例子:

3121 1025
1 1


2 解题思路

2.1 求总的桃子数

  假设桃子一起有x个,第i只猴子用aia_i表示,第一只儿子拿走的桃子数为:a1=15(x−1)a_1=\frac{1}{5}(x-1)。第二只儿子拿走的桃子数为:a2=(4a1−1)5a_2=\frac{(4a_1-1)}{5},第三只猴子拿走的桃子数为:a3=(4a2−1)5a_3=\frac{(4a_2-1)}{5},••••••以此类推。

根据分析有递推关系:

an=(4an−1−1)5a_n=\frac{(4a_{n-1}-1)}{5}⇔5an=4an−1−1⇔5a_n=4a_{n-1}-1⇔5(an+1)=4(an−1+1)⇔5(a_n+1)=4(a_{n-1}+1)

  得

an+1=(45)n−1(a1+1)a_n+1=(\frac{4}{5})^{n-1} (a_1+1)⇔an=(45)n−1(a1+1)−1⇔a_n=(\frac{4}{5})^{n-1} (a_1+1)-1

  又a1=15(x−1)a_1=\frac{1}{5}(x-1)代入可得:

an=(45)n−1(15(x−1)+1)−1a_n=(\frac{4}{5})^{n-1} (\frac{1}{5} (x-1)+1)-1⇔an=4n−15n(x+4)−1⇔a_n=\frac{4^{n-1}}{5^n} (x+4)-1

  因为ana_n为整数,所以x+4x+4是5n5^n的倍数。要取xx最小,令x+4=5nx+4=5^n,得:

x=5n−4x=5^n-4

  即为所求的总的桃子数。

2.2 所有小猴子分得的桃子数

  所有小猴子分得的桃子数:

∑i=1nai\sum_{i=1}^na_i⇔∑i=1n((45)i−1(ai+1)−1)⇔\sum_{i=1}^n((\frac{4}{5})^{i-1}(a_i+1)-1)⇔(ai+1)∑i=1n(45)i−1−n⇔(a_i+1)\sum_{i=1}^n(\frac{4}{5})^{i-1}-n⇔(ai+1)(1−(45)n1−45)−n⇔(a_i+1)(\frac{1-(\frac{4}{5})^n}{1-\frac{4}{5}})-n

  又,a1=15(x−1)a_1=\frac{1}{5} (x-1),x=5n−4x=5^n-4,得:

a1=5n−1−1a_1=5^{n-1}-1

  再得:

5n−1(1−(45)n1−45)−n5^{n-1}(\frac{1-(\frac{4}{5})^n}{1-\frac{4}{5}})-n⇔4∗5n−1−4n−n⇔4*5^{n-1}-4^n-n

  因此小猴子们分的桃子总数为:

5n−4n−n5^n-4^n-n

2.3 老猴子最后获得的桃子数

5n−4−(5n−4n−n)5^n-4-(5^n-4^n-n)⇔4n+n−4⇔4^n+n-4

3 算法实现

import java.util.Scanner;

/**
* Author: 王俊超
* Time: 2016-05-07 08:13
* CSDN: http://blog.csdn.net/derrantcm * Github: https://github.com/Wang-Jun-Chao * Declaration: All Rights Reserved !!!
*/
public class Main {
public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
while (scanner.hasNext()) {
int n = scanner.nextInt();
if (n == 0) {
break;
}

long[] r = peach(n);
System.out.println(r[0] + " " + r[1]);
}

scanner.close();
}

/**
* 分桃子
* <p>
* 解题思路:见PDF或者WORD
*
* @param n 小猴子的数目
* @return 长度为二的一维数组,第一个表示最少的桃子数目,第二个表示老猴子最小可以得到的桃子数
*/
private static long[] peach(int n) {
long power5 = 1;
long power4 = 1;

for (int i = 0; i < n; i++) {
power4 *= 4;
power5 *= 5;
}

return new long[]{power5 - 4, power4 + n - 4};
}
}


4 测试结果



5 其它信息

因为markddow不好编辑,因此将文档的图片上传以供阅读。Pdf和Word文档可以在Github上进行【下载>>>】





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: