问题:
西蒙.丹尼斯.泊松是著名的法国数学家和物理学家。据说在他遇到某个古老的谜题之后,就开始对数学感兴趣了,这个谜题是这样的:给定一个装满水的8品脱壶以及两个容量分别为5品脱和3品脱的空壶,如何通过完全灌满或者倒空这些壶从而使得某个壶精确地装有4品脱的水。

问题分析与解决思路:
通过对问题的分析,拟采用广度优先遍历来解决该问题。由于初始状态是8品脱的壶里装满水,5品脱和3品脱的壶为空壶,我们可以先将三个壶的状态标示为:800,然后我们开始拓展这个数所有能到达的状态(括号里的水是上一状态):350(800)、503(800),然后我们继续拓展这一状态可能到达的状态,并且不能和之前的状态出现重复,下一状态:053(350)、323(350)、530(503),继续寻找下一可能到达的状态:620(323)、233(530),继续寻找下一可能到达的状态:602(620)、251(233),继续寻找下一可能到达的状态:152(602)、701(251),继续寻找下一可能到达的状态:143(152),至此,我们已经得到了4品脱的水。

模型建立与算法描述
我们将上述分析过程和解决的思路进一步归纳为以下步骤:
(1)将初始状态800加入遍历序列,开始遍历。
(2)首先判断是否能倒水,仅当倒水的壶为空或者被倒水的壶为满时不能倒水。
(3)判断倒水的壶是否能倒光,并更新三个壶的状态。
(4)判断是否有壶中水为4品脱,若有则结束遍历。
(5)判断该状态之前是否出现过,若未出现过,将此状态加入到遍历序列中
(6)重复(2)、(3)、(4)操作。

伪代码:

算法 pourwater(int[] nownum)
for(int i:0->3){for(int j:0->3){if(i!=j){if(judge_pour(i,j,nownum)){if (nownum[i] + nownum[j] > maxwater[j]) {nownum[i] = nownum[i] - (maxwater[j] - nownum[j]);nownum[j] = maxwater[j];}else {nownum[j] = nownum[i]+nownum[j];nownum[i] = 0;}if(nownum[0] == 4 || nownum[1] == 4 || nownum[2] == 4)结束遍历;if(!judge_exist(state,nownum[0] + nownum[1] +nownum[2])){state.add(nownum[0] + nownum[1] + nownum[2]);list.add(nownum[0] + nownum[1] + nownum[2]);}
}}}}
算法 judge_pour(int index,int target,int[] num)
if(num[index]==0)//空return false;else{if(num[target]==maxwater[target])//满return false;else{return true;}}
算法 judge_exist(List<String> list, String s)for(String str:list){if(str.equals(s))return true;}return false;

算法实现
首先我们用一个int型数组来存储每个水壶的最大容量:8、5、3,再用两个String类型的ArrayList分别来存储广度优先遍历序列和用于广度优先遍历查找。ArrayList 是 java 集合框架中比较常用的数据结构。继承自 AbstractList,实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在。ArrayList 是支持快速访问、复制、序列化的。
在程序运行时,首先将初始状态800加入ArrayList,然后进行倒水操作,在倒水操作中再不断将下一个要遍历的序列加入ArrayList中,直到有水壶出现4品脱的水。

程序实现

import java.util.ArrayList;
import java.util.List;public class A4 {static int[] water={8,0,0};static int[] maxwater={8,5,3};static List<String> state=new ArrayList<>();//存放广度优先遍历序列static List<String> list=new ArrayList<>();//用于广度优先遍历查找  存放上一个状态public static void main(String[] args){state.add(water[0]+""+water[1]+""+water[2]);//初始状态pour_water(water);for(int k=0;k<list.size();k++){int[] newnum={Integer.parseInt(list.get(k).charAt(0)+""),Integer.parseInt(list.get(k).charAt(1)+""),Integer.parseInt(list.get(k).charAt(2)+"")};pour_water(newnum);}for(String str:state){System.out.println(str);}}public static void pour_water(int[] num){int[] nownum=num;for(int i=0;i<3;i++){for(int j=0;j<3;j++){if(i!=j){if(judge_pour(i,j,nownum)) {int m=nownum[i],n=nownum[j];//如果i水壶不能倒光if (nownum[i] + nownum[j] > maxwater[j]) {nownum[i] = nownum[i] - (maxwater[j] - nownum[j]);nownum[j] = maxwater[j];}// i水壶能倒光else {nownum[j] = nownum[i]+nownum[j];nownum[i] = 0;}if (nownum[0] == 4 || nownum[1] == 4 || nownum[2] == 4) {state.add(nownum[0] + "" + nownum[1] + "" + nownum[2]);list.remove(list.size()-1);return;}//state不存在该状态时将该状态分别加到allstate和listif(!judge_exist(state,nownum[0] + "" + nownum[1] + "" + nownum[2])){state.add(nownum[0] + "" + nownum[1] + "" + nownum[2]);list.add(nownum[0] + "" + nownum[1] + "" + nownum[2]);}nownum[i]=m;nownum[j]=n;}}}}}//判断是否能倒水public static boolean judge_pour(int index,int target,int[] num){if(num[index]==0)//空return false;else{if(num[target]==maxwater[target])//满return false;else{return true;}}}//判断该状态是否已经遍历public static boolean judge_exist(List<String> list, String s){for(String str:list){if(str.equals(s))return true;}return false;}}

算法分析与设计—— 遍历问题【给定一个装满水的8品脱壶】相关推荐

  1. 英语字母表计算机,计算机汇编课程设计CCCC.pdf_给定一个英文ascii码文件,统计文件中英文字母的频率,以十进制形式输出。,wwwwwxxxxx...

    1.给定一个英文ASCII码文件,统计文件中英文字母的频率,以十进制形式输出. 2.用递归计算n!(n≥50), 以十进制数输出 输入一个不小于50的整数n,用递归计算n!, 以十进制数输出 3.存储 ...

  2. 【408计算机考研】|【2018统考真题-41】| 给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数

    目录 一.题目 二.解答 三.测试数据 一.题目   给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算 法,找出数组中未出现的最小正整数.例如,数组{-5, 3, 2, 3}中未 ...

  3. 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。

    笔者初涉<算法设计与分析>这门专业课,在做一些算法设计题的过程中遇到一些小感悟,特此记录和大家分享. 下面直接给出算法题目: 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高 ...

  4. 问题描述 给定一个由n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。 对于给定的由n行数字组成的数字三角形,计算从三角形的顶至底

    问题描述 给定一个由n行数字组成的数字三角形如下图所示.试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大. 对于给定的由n行数字组成的数字三角形,计算从三角形的顶至底的路径 ...

  5. 编译原理实验报告_任意给定一个正规式 r (包括连接、或、闭包运算),根据 Thompson算法设计一个程序,生成与该正规式等价的 NFA N 。

    任意给定一个正规式 r (包括连接.或.闭包运算),根据 Thompson算法设计一个程序,生成与该正规式等价的 NFA N . 百度网盘下载 传送门 提取码:bzjn

  6. 中北大学算法分析与设计实验报告一(BF算法)

    中北大学算法分析与设计实验报告一(BF算法) 1.实验名称 实验一 算法基础实验:数理基础与串匹配程序设计 2.实验目的 以字符串匹配问题为例,结合C等编程语言和链表.堆.栈等数据结构知识,基于BF算 ...

  7. 算法分析与设计课程复习之回溯法

    算法分析与设计课程复习之回溯法 一.基本思想 1.解空间 设问题的解向量为X=(x1,x2,-,xn) ,xi的取值范围为有穷集Si .把xi的所有可能取值组合,称为问题的解空间.每一个组合是问题的一 ...

  8. 算法分析与设计exp3 PrimKruskal C语言代码

    这是中科大2020年春<算法分析与设计>的课程实验3. 实验题目 助教给出补充,所给树的节点一定是20,也就是说默认输入输出都是一个20*20的矩阵. 我已经在GitHub上传我的代码和测 ...

  9. 算法分析与设计——贪心法实验报告

       算法导论  课程设计 成 绩 题    目:    贪心法 学院班级:        1613013         学    号:      16130130216       姓    名: ...

最新文章

  1. 四、管理网站(一) Using the command line interface
  2. DeepMind激起千层浪的这篇论文,并非无所不能
  3. 《Agile Impressions》作者问答录
  4. Unicode、UTF-8、UTF-16
  5. MFC中实现的画箭头算法 (Arrow in MFC)
  6. html5表单注册应用
  7. 题解P3711:【仓鼠的数学题】
  8. Less/Sass 定制私人常用方法库
  9. JavaSE学习--面向对象
  10. vs2015开发activex控件资料
  11. 苹果7p大音频脚位图_苹果7P无声音与杂音维修案例
  12. 怎样删除服务器内磁盘阵列信息,如何管理你的磁盘阵列
  13. 三个小故事让你一次记住双拼输入法口诀
  14. 一些有趣的Shodan搜索
  15. imac下修改本地hosts文件解决react项目中的跨域问题
  16. 适合创业起步看的书推荐
  17. 资源分配问题(动态规划)
  18. matlab画波动图像,【基于Matlab的波动方程的可视化实现最终版材料】
  19. lua的使用(摘自luachina)
  20. 联发科彻底慌了,不仅高端市场保不住,中端市场也被高通压制

热门文章

  1. QT软件开发: 使用QImage创建一张空图片
  2. ac3/eac/eac+atmos编码同步帧参数概述
  3. Blender 是一款免费开源的 3D 创作套件
  4. 【成像】【6】太赫兹光学——理想光学系统的高斯波束传输
  5. 硬盘结构损坏且无法读取怎么办
  6. android html超链接颜色,如何在android中更改超链接的颜色
  7. 422器件与lvds接收器的区别_一文读懂RS232与RS422及RS485三者之间的特性与区别
  8. 成为一名成熟优质的亚马逊运营,这几个能力你必须具备
  9. 许多大学生喜欢玩计算机游戏英语作文,网络游戏的英语作文.doc
  10. Mathematica三维坐标系的建立