算法-猴子搬香蕉
问题描述:
一个小猴子边上有100根香蕉,它要走过50米才能到家,每次它最多搬50根香蕉。它每走1米就要吃掉一根,请问它最多能把多少根香蕉搬到家里呢? 提示:他可以把香蕉放下往返的走,但是必须保证它每走一米都能有香蕉吃。也可以走到n米时,放下一些香蕉,拿着n根香蕉走回去重新搬50根。
程序实现:
接口:
- public interface MonkeysMoveBananas {
-
- /**
- *
- * @param num 总数量 如100
- * @param maxNum 每次最多搬多少个 如50个
- * @param distance 距离 如50
- * @param eatNum 每走一米吃的数量, 如1个
- *
- * @return 到家剩余的数量,或者无法再搬香蕉时剩余的数量
- *
- */
- int Move(int num, int maxNum, int distance, int eatNum);
- }
实现类:
- /**
- * @category 猴子搬香蕉问题
- * @author song
- */
- public class MonkeysMoveBananasImpl implements MonkeysMoveBananas {
-
- /**
- *
- * @param num 总数量 如100
- * @param maxNum 每次最多搬多少个 如50个
- * @param distance 距离 如50
- * @param eatNum 每走一米吃的数量, 如1个
- *
- * @return 到家剩余的数量,或者无法再搬香蕉时剩余的数量
- *
- */
-
- public int Move(int num, int maxNum, int distance, int eatNum) {
-
- /* 已经搬到的位置, 即搬了几米 */
- int location = 0;
-
- /* 每次搬运起始点剩的数量 */
- int CurrentNumberS = num;
-
- /* 每次搬运终点剩的数量 */
- int CurrentNumberE = 0;
-
- /* 外层循环一次, 即把所有剩余香蕉移动一个位置 */
- while(location < distance && CurrentNumberS > eatNum) {
- System.out.println( "当前所在位置" + location + "有" + CurrentNumberS + "个香蕉");
-
- /* 内层循环一次, 即把剩余香蕉移动一个位置, 是移动一个位置的具体细节 */
- while (true) {
-
- if(CurrentNumberS > maxNum) {
- MoveOnePosition(location, location+ 1, maxNum, eatNum);
- CurrentNumberS -= maxNum;
- CurrentNumberE += maxNum -eatNum;
- } else {
- MoveOnePosition(location, location+ 1, CurrentNumberS, eatNum);
- CurrentNumberE += CurrentNumberS - eatNum;
- CurrentNumberS = 0;
- }
-
- /* 看需不需要搬起点剩下的, 即需不需要返回 */
- if(CurrentNumberS >= eatNum * 2) {
- MoveOnePosition(location+ 1, location, -1, eatNum);
- CurrentNumberE -= eatNum;
- } else {
- break;
- }
- }
-
- CurrentNumberS = CurrentNumberE;
- CurrentNumberE = 0;
- location ++;
- }
-
- System.out.println( "剩余" + CurrentNumberS + "个");
- return CurrentNumberS;
- }
-
- /**
- *
- * @param from 起始位置
- * @param to 目标位置
- * @param number 搬的数量
- * @param eatNum 搬一米吃的数量
- */
- private void MoveOnePosition(int from, int to, int number, int eatNum) {
- if(number != -1) {
- System.out.println( "从 " + from + " 位置搬 "+ number + " 个到 " + to + " 位置, 消耗" + eatNum + "个");
- } else {
- System.out.println( "从 " + from + " 位置回到 " + to + " 位置, 消耗 " + eatNum + "个");
- }
- }
- }
测试类:
- public class MonkeysMoveBananasTest {
-
- private static MonkeysMoveBananas monkeysMoveBananas = null;
-
-
- public static void setUpBeforeClass() throws Exception {
- monkeysMoveBananas = new MonkeysMoveBananasImpl();
- }
-
-
- public void moveTest() {
- int k = monkeysMoveBananas.Move(100, 50, 50, 1);
- assertEquals(k, 16);
-
- k = monkeysMoveBananas.Move( 1000, 50, 50, 2);
- assertEquals(k, 20);
- }
- }
-