小知识,大挑战!本文正在参与“ 程序员必备小知识
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
一个猴子身带100个香蕉,他距离家50米。这个猴子要带香蕉回去,但是他一次最多只能背50个香蕉,而且,每走一米他就要吃掉一个香蕉(往 回走也要吃香蕉)。这个猴子最后最多可以带多少个香蕉到家??
public class Mb {
public static void main(String... arg) {
recursiveMove(100, 50, 50, 1);
move(100, 50, 50, 1);
//recursiveMove(3000, 1000, 1000, 1);
}
/**
* 循环算法
* @param total 总数量
* @param capacity 每次最多搬多少个
* @param distance 距离
* @param eatNum 每走一米吃的数量
* @return 到家剩余的数量
**/
public static void move(int total, int capacity, int distance, int eatNum) {
// 已经搬到的位置, 即搬了几米
int location = 0;
// 每次搬运起始点剩的数量
int currentStartNum = total;
// 每次搬运终点剩的数量
int currentEndNum = 0;
// 所有剩余香蕉移动一个位置
while (location < distance && currentStartNum > eatNum) {
System.out.println("当前所在位置" + location + "剩下" + currentStartNum + "个香蕉");
// 每筐香蕉移动一个位置, 是移动一个位置的具体细节
// 如果搬运起点还剩2个,返回去已经没有意义
while (currentStartNum > eatNum * 2) {
if (currentStartNum > capacity) {
moveOnePosition(location, location + 1, capacity, eatNum);
currentStartNum -= capacity;
currentEndNum += capacity - eatNum;
} else {
moveOnePosition(location, location + 1, currentStartNum, eatNum);
// 直接向前走
currentEndNum += currentStartNum - eatNum;
currentStartNum = 0;
}
// 需不需要搬起点剩下的, 即需不需要返回
if (currentStartNum > eatNum * 2) {
moveOnePosition(location + 1, location, -1, eatNum);
currentEndNum -= eatNum;
}
}
currentStartNum = currentEndNum;
currentEndNum = 0;
location++;
}
if (location < distance) {
System.out.println("---猴子爬不到终点,饿死了---");
} else {
System.out.println("成功走到终点, 剩余" + currentStartNum + "个");
}
}
/**
* 递归算法
* @param total 总数量
* @param capacity 每次最多搬多少个
* @param distance 距离
* @param eatNum 每走一米吃的数量
* @return 到家剩余的数量
**/
public static void recursiveMove(Integer total, Integer capacity, Integer distance, Integer eatNum) {
// 已经搬到的位置
Integer location = 0;
// 每次搬运起始点剩的数量
Integer currentStartNum = total;
// 每次搬运终点剩的数量
Integer currentEndNum = 0;
stepMove(location, distance, capacity, currentStartNum, currentEndNum, eatNum);
}
private static void stepMove(int location, int distance, int capacity, int currentStartNum, int currentEndNum, int eatNum) {
if (location < distance && currentStartNum > eatNum) {
// 所有剩余香蕉移动一个位置
System.out.println("当前所在位置" + location + "剩下" + currentStartNum + "个香蕉");
// 每筐香蕉移动一个位置, 是移动一个位置的具体细节
// 如果搬运起点还剩2个,返回去已经没有意义
currentEndNum = miniStep(location, distance, capacity, currentStartNum, currentEndNum, eatNum);
// 向前挪一步
currentStartNum = currentEndNum;
currentEndNum = 0;
location++;
stepMove(location, distance, capacity, currentStartNum, currentEndNum, eatNum);
} else {
if (location < distance) {
System.out.println("---猴子爬不到终点,饿死了---");
} else {
System.out.println("成功走到终点, 剩余" + currentStartNum + "个");
}
}
}
private static int miniStep(int location, int distance, int capacity, int currentStartNum, int currentEndNum, int eatNum) {
if (currentStartNum > eatNum * 2) {
if (currentStartNum > capacity) {
moveOnePosition(location, location + 1, capacity, eatNum);
currentStartNum -= capacity;
currentEndNum += capacity - eatNum;
} else {
moveOnePosition(location, location + 1, currentStartNum, eatNum);
// 直接向前走
currentEndNum += currentStartNum - eatNum;
currentStartNum = 0;
}
// 需不需要搬起点剩下的, 即需不需要返回
if (currentStartNum > eatNum * 2) {
moveOnePosition(location + 1, location, -1, eatNum);
currentEndNum -= eatNum;
}
return miniStep(location, distance, capacity, currentStartNum, currentEndNum, eatNum);
} else {
return currentEndNum;
}
}
/**
* @param from 起始位置
* @param to 目标位置
* @param count 搬的数量
* @param eatNum 搬一米吃的数量
*/
private static void moveOnePosition(int from, int to, int count, int eatNum) {
if (count != -1) {
System.out.println("从位置" + from + "搬" + count + "个到位置" + to + ", 吃掉" + eatNum + "个");
} else {
System.out.println("从位置" + from + "返回到位置" + to + ", 吃掉 " + eatNum + "个");
}
}
}