题目一
一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
解题思路:因为是每经过一个村庄会卖掉一本又一只,经过第七个村庄后还剩两只,按照要求,如果还经过一个村庄也就是第八个村庄后,鸭子数量就会为0,本题目解题使用一个count临时变量来统计所经过的村庄的数目。使用递归的解法,当鸭子数目不为0或者1时就可以再去下一个村庄,而当前的鸭子数量就为(number/2-1)number表示鸭子数目。当前鸭子数量为为0时就可以返回经历的村庄数目count
实现
/**
*
* @Title: Dunk.java
* @Package one
* @Description: 递归求得买鸭子问题
* @author: Jl
* @date: 2018年11月17日 下午5:37:51
* @version V1.0
*/
public class Dunk {
static int count;//用来统计经过的村庄数量
/**
*
* @Title: sale
* @Description: TODO(这里用一句话描述这个方法的作用)
* @author: Jl
* @param: @param number 当前的鸭子数量
* @param: @return 当鸭子已经卖完就返回经过的村庄数量
* @return: int
* @throws
*/
public static int sale(int number) {
if(number==0)
return count;
if(number==1)
return 1;
count++;
System.out.println("第"+count+"个"+"卖出"+(number/2+1)+"个");
return sale(number/2-1); //当前的鸭子数量只要不是0或者1就可以递归
}
/**
*
* @Title: main
* @Description: 因为经过七个村庄后还剩三只鸭子,所以在经过第八个村庄后就会买光所有的鸭子
* @author: Jl
* @param: @param args
* @return: void
* @throws
*/
public static void main(String[] args) {
for(int j=0;j<1024;j += 2) {//从1到1024测试,
count=0;
if(sale(j)==8) {//只要满足到第八个村庄后鸭子数量为0,该数量就是初始的数量。
System.out.println("总共的鸭子数目为:"+j);
break;
}
}
}
}
题目二
角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。
解题思路:此问题用递归会很好解决,只要判断当前的值的奇偶性就可以按照要求进行下一次值得递归的代入
实现
package two;
/**
*
* @Title: GuJiao.java
* @Package two
* @Description: 谷角定理
* @author: Jl
* @date: 2018年11月17日 下午5:54:24
* @version V1.0
*/
public class GuJiao {
static int count = 0; //计算步数
/**
*
* @Title: getCount
* @Description: 递归解决谷角定理
* @author:Jl
* @param: @param number 当前所判断的数
* @return:当值为1所经历的步数
* @throws
*/
static public int getCount(int number) {
count++;
System.out.print(number+" ");
if(number==1)//当前数为1,返回
return count;
if(number%2==0) {//偶数就除以2
return getCount(number/2);
}
else {//奇数乘以3加1
return getCount(number*3+1);
}
}
public static void main(String[] args) {
for(int i=1;i<11;i++) {
count = 0;
System.out.println(" 进行:"+getCount(i)+"步");
}
}
}
题目三
电话号码对应的字符组合:在电话或者手机上,一个数字如2对应着字母ABC,7对应着PQRS。那么数字串27所对应的字符的可能组合就有3*4=12种(如AP,BR等)。现在输入一个3到11位长的电话号码,请打印出这个电话号码所对应的字符的所有可能组合和组合数。
解题思路:本题目主要包括两个方面,一个是获取一个数字对应的字母的个数,另一方面是可以通过递归遍历字符串的每个字符,用当前字符所对应的字母个数乘以后面的字符所对应的个数,直到进行到最后一个字符
package three;
/**
*
* @Title: NumberCombin.java
* @Package three
* @Description: 解决数字组合问题
* @author: Jl
* @date: 2018年11月17日 下午5:44:59
* @version V1.0
*/
public class NumberCombin {
/**
*
* @Title: numberCount
* @Description: 该方法用于求得每一个数字表示的可能的情况个数
* @author:Jl
* @param: @param number 当前数字
* @param: @return
* @return: int 当前数字表示的字母个数
* @throws 电话号格式异常
*/
static public int numberCount(char number) {
if(number=='1')
return 0;
if(number=='2'||number=='3'||number=='4'||number=='5'||number=='6'||number=='8')
return 3;
if(number=='7'||number=='9')
return 4;
else throw new RuntimeException("电话号码格式不正确");//电话号格式错误
}
/**
* @Title: getCount
* @Description: 用于用户求组合个数的共有方法
* @author: Jl
* @param: @param phoneNumber 电话号字符串
* @return: int
* @throws 电话号长度异常
*/
static public int getCount(String phoneNumber) {
if(phoneNumber.length()<3||phoneNumber.length()>11)//判断长度是否符合要求
throw new RuntimeException("电话号码长度不正确");
return getCount(phoneNumber,0);
}
/**
* @Title: getCount
* @Description: 重载的方法,该方法只要用于递归表示
* @author: jl
* @param: @param phoneNumber 电话号字符串
* @param: @param index 当前的字符串进行计算的下标索引
* @return: 在index之前的组合可能数
* @throws
*/
static private int getCount(String phoneNumber,int index) {
if(index==phoneNumber.length()) {//超出字符串长度
return 1;
}else {
int curr = numberCount(phoneNumber.charAt(index));
return curr*getCount(phoneNumber,index+1);//从当前的*下一个的结果
}
}
public static void main(String[] args) {
System.out.println(getCount("222222222223"));
}
}
题目四
日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完 后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?
解题思路:本题目使用了倒推的思路,因为他们最后分到的橘子数目是一样多的,所以,可以得到,每个人分到的橘子数为420个,而老六是把自己的1/3分给了老大,所以从这里可以看出来老六得到老五橘子后的的橘子总数为420*3/2=630,分给老大的是210,因为老大最后的橘子数目为420,所以,在分给后,老六还没有分给他橘子之前,还有210个,而老大把自己的1/8分给老二,所以在老大分给老二前的橘子数目为240,依次类推。没有采用递归的实现思路
实现
package four;
/**
*
* @Title: Orange.java
* @Package four
* @Description: 解决“父亲将2520个桔子分给六个儿子”的问题
* @author: Jl
* @date: 2018年11月17日 下午5:29:59
* @version V1.0
*/
public class Orange {
/**
* @Title: distri
* @Description: 该方法用来求解每人初始的橘子数量,主要是采用了倒推的方法。
* @author: Jl
* @param:
* @return: void
* @throws
*/
public static void distri() {
// 每个人最终的橘子数量一致,所以每个人最终都是420个橘子
int[] apple = new int[] { 420, 420, 420, 420, 420, 420 };// 最终的苹果数量
for (int i = 1; i < 6; i++)// 求每个人得到橘子后的橘子数量
apple[i] = apple[i] * (8 - i) / (7 - i);
// 可以算出老六分给老大的橘子数量为210,所以,老大在分给老二后的橘子数量为210
apple[0] = 210 * 8 / 7; // 老大分给老二前的橘子数量
for (int i = 5; i > 0; i--)// 求得到橘子之前每个人的橘子数量,apple[i-1]/(9-i)表示从上一家得到的橘子
apple[i] = apple[i] - apple[i - 1] / (9 - i);
for (int i = 0; i < 6; i++) {
System.out.println("老" + (i + 1) + "的橘子数量为: " + apple[i]);
}
}
public static void main(String[] args) {
distri();
}
}