日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完 后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?
(1) 题目分析
分析题目可以发现只有第一个儿子与其他儿子不一样,第一个儿子是先分后加,其他儿子都是先加后分,那我想突破口应该就在想这,再思索一下第六个孩子,由第六个儿子橘子数x*(1-1/3)=420;可得x=630,第六个儿子给大儿子分了1/3 =210个桔子,由y*7/8+210=420可以得出第一个儿子的初始桔子数y=240,因此便可递归的求解下去
(2)算法构造:
这里用两个数组:
int[] st = { 420, 420, 420, 420, 420, 420 };//纪录每个儿子初始的桔子数量
int[] st1={0,0,0,0,0,0};//记录每个儿子即将分出桔子时的桔子数 ,初始为0
大孩子的初始初始桔子数和即将分出橘子时的桔子数相等
首先计算出第一个孩子的初始橘子数,
if(j==0){
int x=(420-4203/21/3)*i/(i-1);//计算出大儿子的初始桔子数
st[j]=x;// 大儿子的初始桔子数,也是即将分出桔子之前的桔子数
st1[j]=x;
}
然后利用公示递归的算出每个孩子的桔子数
int y=st[j]*i/(i-1)-st1[j-1]*1/(i+1);//计算出对应儿子的初始桔子数
st1[j]=st[j]*i/(i-1);//即将分出桔子之前的桔子数
st[j]=y;
递归体:
if(j==0){
int x=(420-420*3/2*1/3)*i/(i-1);//计算出大儿子的初始桔子数
st[j]=x;// 大儿子的初始桔子数,也是即将分出桔子之前的桔子数
st1[j]=x;
}
i=i-1;//变量分母减一
j=j+1;//数据下标加一
if(j<=5){//避免数组越界
int y=st[j]*i/(i-1)-st1[j-1]*1/(i+1);//计算出对应儿子的初始桔子数
st1[j]=st[j]*i/(i-1);//即将分出桔子之前的桔子数
st[j]=y;
递归出口:j>6:
(3)函数实现:
public void Orangs(int j,int i){
if(j==0){
int x=(420-420*3/2*1/3)*i/(i-1);//计算出大儿子的初始桔子数
st[j]=x;// 大儿子的初始桔子数,也是即将分出桔子之前的桔子数
st1[j]=x;
}
i=i-1;//变量分母减一
j=j+1;//数据下标加一
if(j<=5){//避免数组越界
int y=st[j]*i/(i-1)-st1[j-1]*1/(i+1);//计算出对应儿子的初始桔子数
st1[j]=st[j]*i/(i-1);//即将分出桔子之前的桔子数
st[j]=y;
Orangs(j,i);//当未算到最后一个儿子时,递归调用继续计算
}
System.out.println("第"+(j)+"个儿子原始桔子数为"+st[j-1]);//打印出st[]数组对应的儿子的桔子数
}
(4)运行截图:
源代码
/**
* @类描述:日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。
* 分完 后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;
* 老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;
* 老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。
* 结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?
* @类名称:Orange
* @创建人:司志杰
* @创建时间:2018年11月18日下午2:22:35
* @修改人:司志杰
* @修改时间:2018年11月18日下午2:22:35
* @修改备注:
* @version v1.0
* @mail 1904479327@qq.com
*/
public class Orange {
static int j = 0;//记录数组下标
static int i = 8;//;类似于1/8,记录分母的变量,初始为8
int[] st = { 420, 420, 420, 420, 420, 420 };//纪录每个儿子初始的桔子数量
int[] st1={0,0,0,0,0,0};//记录每个儿子即将分出桔子时的桔子数 ,初始为0
public static void main(String args[]) {
new Orange().Orangs(j,i);
}
/**
* @描述:用来计算每个二字初始桔子数的函数
· 分析题目可以发现只有第一个儿子与其他儿子不一样,第一个儿子是先分后加,其他儿子都是先加后分
因此由第六个儿子橘子数st1【5】*(1-1/3)=420;可得st1[5]=630 第六个儿子给大儿子分了210个桔子
所以由st【0】*7/8+210=420可以得出第一个儿子的初始桔子数240,因此便可求解下去
* @方法名: Orangs
* @param j
* @param i
* @返回类型 void
* @创建人 szj
* @创建时间 2018年11月18日下午2:29:38
* @修改人 szj
* @修改时间 2018年11月18日下午2:29:38
* @修改备注
*/
public void Orangs(int j,int i){
if(j==0){
int x=(420-420*3/2*1/3)*i/(i-1);//计算出大儿子的初始桔子数
st[j]=x;// 大儿子的初始桔子数,也是即将分出桔子之前的桔子数
st1[j]=x;
}
i=i-1;//变量分母减一
j=j+1;//数据下标加一
if(j<=5){//避免数组越界
int y=st[j]*i/(i-1)-st1[j-1]*1/(i+1);//计算出对应儿子的初始桔子数
st1[j]=st[j]*i/(i-1);//即将分出桔子之前的桔子数
st[j]=y;
Orangs(j,i);//当未算到最后一个儿子时,递归调用继续计算
}
System.out.println("第"+(j)+"个儿子原始桔子数为"+st[j-1]);//打印出st[]数组对应的儿子的桔子数
}
}