本文为joshua317原创文章,转载请注明:转载自joshua317博客 算法-经典趣题-青蛙过河 - joshua317的博客

一、问题

青蛙过河是一个非常有趣的智力游戏,其大意如下:

一条河之间有若干石块间隔,有两队青蛙在过河,每队有3只青蛙,如图所示。这些青蛙只能向前移动,不能向后移动,且一次只能有一只青蛙向前移动。在移动过程中,青蛙可以向前面的空位中移动,不可一次跳过两个位置,但是可以跳过对方一只青蛙进入前面的一个空位。问两队青蛙该如何移动才能够用最少的步数分别走向对岸?

二、分析

我们来分析一下青蛙过河问题。可以采用如下方案来移动青蛙,操作步骤如下:

(1)左侧的青蛙向右跳过右侧的一只青蛙,落入空位,执行第(5)步。

(2)右侧的青蛙向左跳过左侧的一只青蛙,落入空位,执行第(5)步。

(3)左侧的青蛙向右移动一格,落入空位,执行第(5)步。

(4)右侧的青蛙向左移动一格,落入空位,执行第(5)步。

(5)判断是否已将两队青蛙移到对岸,如果没有则继续从第(1)步执行,否则结束程序。

三、编程

package com.joshua317;import jdk.nashorn.internal.ir.LiteralNode;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class Main {public static void main(String[] args) {FrogCrossRiver frogCrossRiver = new FrogCrossRiver();List frogQueue = frogCrossRiver.initFrogQueue();String frogJumpInfo = (frogCrossRiver.frogJump(frogQueue, 3));System.out.println("青蛙跳跃的顺序为:\r\n " + frogJumpInfo);}
}class Frog {static enum frogDirection {向左, 向右};public String frogName;//青蛙名称public int position;//青蛙位置public frogDirection direction;//青蛙跳动的方向public boolean canJump;//是否可以跳public boolean isEmpty = false;//是否是空格//构造函数public Frog (int position, String frogName, frogDirection direction, boolean canJump) {this.position = position;this.frogName = frogName;this.direction = direction;this.canJump = canJump;}public Frog (int position) {this.frogName = "空";this.position = position;this.canJump = false;this.isEmpty = true;}public Frog (Frog frog) {this.position = frog.position;this.frogName = frog.frogName;this.direction = frog.direction;this.canJump = frog.canJump;this.isEmpty = frog.isEmpty;}}class FrogCrossRiver {//初始化青蛙队列public List<Frog> initFrogQueue(){List<Frog> frogQueue = new ArrayList<Frog>();frogQueue.add(new Frog(0, "左1", Frog.frogDirection.向右, false));frogQueue.add(new Frog(1, "左2", Frog.frogDirection.向右, true));frogQueue.add(new Frog(2, "左3", Frog.frogDirection.向右, true));frogQueue.add(new Frog(3));frogQueue.add(new Frog(4, "右1", Frog.frogDirection.向左, true));frogQueue.add(new Frog(5, "右2", Frog.frogDirection.向左, true));frogQueue.add(new Frog(6, "右3", Frog.frogDirection.向左, false));return frogQueue;}//当一个青蛙跳动后,形成一个新的队列private List<Frog> editFrogQueue(List<Frog> frogQueue, String frogName, int oldEmptyPostionId, int newEmptyPostionId){List<Frog> newFrogQueue = new ArrayList<Frog>();for (int i=0; i<frogQueue.size(); i++) {Frog frog = (Frog)frogQueue.get(i);Frog newFrog = new Frog(frog);if (newFrog.isEmpty) {newFrog.position = newEmptyPostionId;}if (newFrog.frogName == frogName) {newFrog.position = oldEmptyPostionId;}newFrog.canJump = false;if ((newEmptyPostionId - newFrog.position) > 0 &&(newEmptyPostionId - newFrog.position) < 3 &&newFrog.direction == Frog.frogDirection.向右) {newFrog.canJump = true;}if ((newFrog.position - newEmptyPostionId) > 0 &&(newFrog.position - newEmptyPostionId) < 3 &&newFrog.direction == Frog.frogDirection.向左) {newFrog.canJump = true;}newFrogQueue.add(newFrog);}return newFrogQueue;}//是否已经完成位置对换,即前三个青蛙的位置都大于3private boolean isComplete(List<Frog> frogQueue){return (frogQueue.get(0).position > 3 && frogQueue.get(1).position > 3 && frogQueue.get(2).position > 3);}//是否还有可以跳动的青蛙,只有可以跳动的,就没有达到最后的状态,//但都不可以跳动了也不一定对换完了,这里只是控制递归private boolean canFrogJump(List<Frog> frogQueue){for (int i=0; i<frogQueue.size(); i++) {Frog frog = (Frog)frogQueue.get(i);if (frog.canJump) {return true;}}return false;}//获取青蛙跳动的步骤public String frogJump(List<Frog> frogQueue, int emptyPositionId){String frogJumpInfo = "";for (int i=0; i<frogQueue.size(); i++) {Frog frog = (Frog)frogQueue.get(i);//是空位置if (frog.isEmpty) {continue;}//不能跳if (!frog.canJump) {continue;}frogJumpInfo = "青蛙" + frog.frogName + " " + frog.direction + "跳到第" + (emptyPositionId + 1) + "个位置" +"\r\n";int newPositionId = frog.position;List<Frog> newFrogQueue = this.editFrogQueue(frogQueue, frog.frogName, emptyPositionId,newPositionId);//只要能继续跳就递归if (this.canFrogJump(newFrogQueue)) {frogJumpInfo += this.frogJump(newFrogQueue, newPositionId);} else {if (this.isComplete(newFrogQueue)) {frogJumpInfo += "成功";break;}}if (frogJumpInfo.contains("成功")) {break;}}return frogJumpInfo;}
}

四、练习

大家可以想一想如果是4只青蛙,5只青蛙,6只青蛙呢?

附一个小游戏的链接:http://www.4399.com/flash/204168_4.htm

本文为joshua317原创文章,转载请注明:转载自joshua317博客 算法-经典趣题-青蛙过河 - joshua317的博客

算法-经典趣题-青蛙过河相关推荐

  1. 算法-经典趣题-三色球

    本文为joshua317原创文章,转载请注明:转载自joshua317博客 算法-经典趣题-三色球 - joshua317的博客 一.问题 三色球是一个排列组合问题,三色球问题的大意如下:一个黑盒中放 ...

  2. 算法-经典趣题-兔子产仔

    本文为joshua317原创文章,转载请注明:转载自joshua317博客 算法-经典趣题-兔子产仔 - joshua317的博客 一.问题 兔子产仔是一个非常古老而经典的问题,其与数论有关.兔子产仔 ...

  3. 算法-经典趣题-窃贼问题

    本文为joshua317原创文章,转载请注明:转载自joshua317博客 算法-经典趣题-窃贼问题 - joshua317的博客 一.问题 窃贼问题是一个典型的最优解的问题.窃贼问题的大意如下: 有 ...

  4. 算法-经典趣题-渔夫捕鱼

    本文为joshua317原创文章,转载请注明:转载自joshua317博客 算法-经典趣题-渔夫捕鱼 - joshua317的博客 一.问题 渔夫捕鱼问题是一个典型的递推问题,渔夫捕鱼问题的大意如下: ...

  5. 数据结构与算法经典程序:农夫过河问题讲解

    首先,在这里祝各位看到这条博客的同学五一快乐呀,今天,我们讲解一个数据结构与算法中的经典题目(小程序),题目如下: 题目: 一个农夫在河边带了一只狼.一只羊和一颗白菜,他需要把这三样东西用船带到河的对 ...

  6. java青蛙过河打字_趣味算法——青蛙过河(JAVA)

    青蛙过河是一个非常有趣的智力游戏,其大意如下: 一条河之间有若干个石块间隔,有两队青蛙在过河,每队有3只青蛙,这些青蛙只能向前移动,不能向后移动,且一次只能有一只青蛙向前移动.在移动过程中,青蛙可以向 ...

  7. 程序员的算法趣题Q66: 设计填字游戏

    目录 1. 问题描述 2. 解题分析 2.1 基本算法流程 2.2 连通性检查 3. 代码及测试 4. 后记 1. 问题描述 2. 解题分析 与前面的Q32.Q59以及后面的Q68(碰巧先做了Q68) ...

  8. java 独木桥_趣味算法——青蛙过河(JAVA)

    青蛙过河是一个非常有趣的智力游戏,其大意如下: 一条河之间有若干个石块间隔,有两队青蛙在过河,每队有3只青蛙,这些青蛙只能向前移动,不能向后移动,且一次只能有一只青蛙向前移动.在移动过程中,青蛙可以向 ...

  9. 100%的程序员都想挑战的算法趣题!| 码书

    计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...

最新文章

  1. Python 爬虫练手项目—酒店信息爬取
  2. java运行在用户态_理解Linux用户态和内核态
  3. Linux-Ubuntu操作记录
  4. html你可能还不知道的一些知识点
  5. CDN服务品质协议1
  6. C语言 函数的封装示例(允许存在同名但形参不同函数)
  7. java webservice接口开发_给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)
  8. 《数学之美》读书笔记和知识点总结(一)
  9. Gibbs 采样定理的若干证明
  10. c语言正则表达式替换,Linux C 支持正则表达式的字符串替换函数...
  11. Mybatis通过原生sql查询Map结果集注意事项
  12. 程序员必读的三十本经典书籍
  13. JSON 对比工具,优秀的JSON对比工具,对比json数据
  14. 联想小新Air2020ill版换硬盘及安装Win11详细过程
  15. 在oracle包体中动态创建表 PKG
  16. 对复利计算器和股票投资的总结
  17. 岁月温柔-18 妈妈在市ICU第8天
  18. HTML5 中的 input 元素的输入类型(type 属性的取值)
  19. ArcGIS 中的标准分类方法(相等、分位、自然断裂、标准差)
  20. Waves效果器离线安装包-Waves v9r30 Offline Install WiN-MAC

热门文章

  1. android html footer 固定,HTML5+CSS把footer固定在底部
  2. windows 环境MySQL 安装启动 、重新安装
  3. 别只关注地段、户型 楼盘隐形品质不能忽视
  4. iPhone 5s 如何进入 DFU 模式,macOS 无法进入 DFU 模式
  5. android简单记账源码,Android+个人记账程序源码.rar(入门级)
  6. Android 练习项目 ——简单记账软件的实现
  7. 如何在微信h5拉起支付宝支付界面
  8. 最初不相识,最终不相认
  9. C# 更换微信小程序码中间的logo图层
  10. 联想拯救者安装Ubuntu 16.04 系统时显示WiFi无法连接被禁用