简单的赶鸭子问题

8 篇文章 0 订阅

(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 1904479327@qq.com
 */
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("测试结果失败");
		}
	}

}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值