简单的赶鸭子问题
(1)问题分析:
每经过一个村子,卖出去所赶鸭子的一半又一只,总共经过七个村子,最后剩余2只鸭子,由题意可知,对于最后一个村子x—(x/2+1)=2 可以到达第七个村子时的鸭子数,也就是经过第六个村子后剩余的鸭子数由此可知,可以一直循环的往回算下去,直到第一个村子
(2)算法构造:
计算公式:
由x—(x/2+1)=剩余数 可得x=2*(剩余数+1) 其中x为刚到达这个村子的鸭子数,剩余数为经过这个村子后的剩余鸭子数
P=x/2+1 等于经过这个村子卖出的鸭子数
递归函数体:
y = 2 * (y + 1);//由y-(y/2+1)=剩余数 得此公式
int p = y / 2 + 1;//p为局部变量 递归时不会相互影响 每个村子卖出的鸭子数 等于刚进入村子的鸭子总数的一半加一
i=i-1;//上一个村子
程序出口:
X<=0
(3)算法实现:(详细在源代码中注释说明)
A:递归形式
public int sellDuck(int i,int y) {
if(i>0) {//村子数必须为正数
y = 2 * (y + 1);//由y-(y/2+1)=剩余数 得此公式
int p = y / 2 + 1;//p为局部变量 递归时不会相互影响 每个村子卖出的鸭子数 等于刚进入村子的鸭子总数的一半加一
i=i-1;//上一个村子
sellDuck(i,y);//递归调用sellduck函数知道村庄数到达1
System.out.println("第" + (i+1) + "个村庄卖出" + p + "只鸭子");//打印每个村庄卖出的鸭子数
}
if(i==0){
counts =y;//当经过第一个村子之前 , y为鸭子总数 将y复制给counts 并返回counts
}
return counts;
}
B:非递归形式
public int sellDuck1() {
int x=2;// 最后剩余的鸭子数
int p=0;//卖出的鸭子数
int y=0;// 到达每个村子的鸭子数,也是经过上一个村子的剩余鸭子数
for(int i=0;i<7;i++) {//采用循环
y=2*(x+1);//由y-(y/2+1)=剩余数 得此公式
p=y/2+1;//每个村子卖出的鸭子数 等于刚进入村子的鸭子总数的一半加一
x=y;// 更新剩余的鸭子数
System.out.println("第"+(7-i)+"个村庄卖出"+p+"只鸭子");
}
return y;////当经过第一个村子之前 , y为鸭子总数 ,返回鸭子总数
}
(4)运行结果:
测试代码:
public static void ceshi(int counts){//传入counts鸭子总数
for (int i = 0; i < 7; i++) {//经过循环,计算经过七个村子发出的鸭子数
counts= counts / 2 - 1;
}if(counts==2){//如果最后剩余2 则结果正确
System.out.println("测试代码,,测试正确,最后剩余"+counts);
}else{
System.out.println("测试结果失败");
}
}
运行截图:
源代码`
/**
* @类描述:一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。
* 这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?
* 经过每个村子卖出多少只鸭子?
* @项目名称:Duck
* @类名称:SzjDuck
* @创建人:司志杰
* @创建时间:2018年11月16日下午12:02:21
* @修改人:Administrator
* @修改时间:2018年11月17日下午12:02:21
* @修改备注:起初未用递归方法,改为递归方法,测试非递归方法与递归方法均正常
* @version v1.1
* @mail [email protected]
*/
public class SzjDuck {
public static int counts=0;//设置全局变量counts 表示总共的鸭子数
public static void main(String[] args) {
SzjDuck duck = new SzjDuck();//实例化szjduck对象 duck
// counts= duck.sellDuck1(); // 调用非递归方法计算
counts = duck.sellDuck(7, 2);// 递归方法计算 调用sellduck方法,计算每个村子卖出的鸭子数与总鸭子数,将总鸭子数counts返回 7为村子数,2为最后剩余鸭子数
System.out.println("总共卖出" +counts+ "鸭子");//打印总鸭子数
ceshi(counts);//调用测试方法,如果最后剩余2与题目相符则打印测试正常,否则打印失败
}
/**
*
* @描述: 非递归方法
* @方法名: sellDuck
* @return counts
* @返回类型 int
* @创建人 szj
* @创建时间 2018年11月18日下午12:46:37
* @修改人 Administrator
* @修改时间 2018年11月18日下午12:46:37
*/
public int sellDuck1() {
int x=2;// 最后剩余的鸭子数
int p=0;//卖出的鸭子数
int y=0;// 到达每个村子的鸭子数,也是经过上一个村子的剩余鸭子数
for(int i=0;i<7;i++) {//采用循环
y=2*(x+1);//由y-(y/2+1)=剩余数 得此公式
p=y/2+1;//每个村子卖出的鸭子数 等于刚进入村子的鸭子总数的一半加一
x=y;// 更新剩余的鸭子数
System.out.println("第"+(7-i)+"个村庄卖出"+p+"只鸭子");
}
return y;////当经过第一个村子之前 , y为鸭子总数 ,返回鸭子总数
}
/**
*
* @描述: 采用递归 传入村子数i=7与最后剩余的鸭子数2采用递归的方法计算每个村子卖出的鸭子数以及总鸭子数
* @方法名: sellDuck
* @return counts总鸭子数
* @返回类型 int
* @创建人szj
* @创建时间 2018年11月18日下午12:15:38
* @修改人 Administrator
* @修改时间 2018年11月18日下午12:15:38
* @修改备注 采用递归方法
*/
public int sellDuck(int i,int y) {
if(i>0) {//村子数必须为正数
y = 2 * (y + 1);//由y-(y/2+1)=剩余数 得此公式
int p = y / 2 + 1;//p为局部变量 递归时不会相互影响 每个村子卖出的鸭子数 等于刚进入村子的鸭子总数的一半加一
i=i-1;//上一个村子
sellDuck(i,y);//递归调用sellduck函数知道村庄数到达1
System.out.println("第" + (i+1) + "个村庄卖出" + p + "只鸭子");//打印每个村庄卖出的鸭子数
}
if(i==0){
counts =y;//当经过第一个村子之前 , y为鸭子总数 将y复制给counts 并返回counts
}
return counts;
}
/**
* @描述:测试方法,将counts鸭子数传入 经过七个村子 如果最后剩余2 与题目相符则打印正确,否则错误
* @方法名: ceshi
* @返回类型 void
* @创建人 szj
* @创建时间 2018年11月18日下午12:10:01
* @修改人 Administrator
* @修改时间 2018年11月18日下午12:10:01
* @throws null
*/
public static void ceshi(int counts){//传入counts鸭子总数
for (int i = 0; i < 7; i++) {//经过循环,计算经过七个村子发出的鸭子数
counts= counts / 2 - 1;
}if(counts==2){//如果最后剩余2 则结果正确
System.out.println("测试代码,,测试正确,最后剩余"+counts);
}else{
System.out.println("测试结果失败");
}
}
}