题目
以前有这么一个益智游戏,沙滩上有n个猴子和一堆香蕉,晚上有一只猴子偷偷起来把香蕉分成n份,自己拿走了一份,多出来一根,扔进了海里,然后去睡觉了,后面所有的猴子都进行了同样的操作,分成n份,扔掉一根,拿走一份。问最少需要多少香蕉才能让所有猴子都完成该操作。(最后一只猴子扔掉后可以拿走0个,也算是n份均分)给定一个整数m,表示猴子的个数,题目要求输出最初的香蕉数。题目保证有解。
实例:
输入
2
2
3
输出
3 25
刚刚看到这个题目简直懵逼啊,为啥两只猴子最少要3根香蕉用来造,为啥3只猴子要25根呢。于是就拿出了珍藏的草稿本一顿算,请看下图
这样一看就明了多了。那么我们到底怎么算一共需要多少只香蕉呢?很明显这里需要应该从最后一次分香蕉入手。
解题思路
假设我就是最后去分香蕉的猴子,我一定会扔掉一只香蕉,并且我均分的香蕉数量是前几只猴子里最少的,甚至可以为0.那么就用枚举的方法,设最后一只猴子均分每份香蕉数量为 i ,i 从0开始。再根据上图可以分析出最后一只猴子去分香蕉时,一共有 m = 1+ ni 只香蕉。也就是倒数第二只猴子留下了 m = 1+ ni 只香蕉。以此类推,倒数第三只猴子就留下了 m = 1 + nm/(n-1) 只香蕉,并且注意m必须是(n-1)的倍数才能被均分。根据这个规律,就可以求得一共需要多少只香蕉。
让我们验证一下,对于3只猴子,n = 3.
当 i = 0时,m = 1,1对2求余不为0 。
当 i = 1时, m = 4,4对2求余为0。因此第二只猴子留下4只香蕉成立。然后第一只猴子就留下m = 1+ 34/2 = 7,7对2求余不为0 。因此第一只猴子留下7根香蕉是不成立的!
当 i = 2时,m = 7,7对2求余不为0.
当 i= 3时,m = 10,10对2求余为0 。因此第二只猴子留下10根香蕉是成立的。那么第一只猴子就留下了m = 1+ 310/2 = 16,16对2 求余为0。因此第一只猴子留下16只香蕉是成立的!那么三只猴子一共需要 1+ 316/2 = 25根香蕉!
敲代码吧
根据上面的规律就可以敲出函数代码啦
import java.util.Scanner;
public class PTA61 {
public static int bananas(int n) {
int m = 0;
for(int i = 0;;i++) {//当最后一只猴子把唯一一根扔掉,那就默认大家都没有香蕉,均分为0.
m = 1+n*i;
int j = 0;
for( j = 0;j<n-1;j++) {
if(m %(n-1) != 0)break;
else {
m = 1 + n*m/(n-1);
}
}
if(j == n -1 )break;
}
return m;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int e = sc.nextInt();//一共有多少组数据
int a[] = new int[e];
for(int i = 0;i<e;i++) {
a[i] = sc.nextInt();
}
for(int j = 0;j<e-1;j++) {
System.out.print(bananas(a[j])+" ");
}
System.out.print(bananas(a[e-1]));
}
}