package com.raylew.algorithm.book1; import java.util.Iterator; import java.util.LinkedList; /* 三个水杯 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。 三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。   输入 第一行一个整数N(0<N<50)表示N组测试数据 接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。 第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态 输出 每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1 样例输入   2 6 3 1 4 1 1 9 3 2 7 1 1 样例输出   3 -1 */ public class 倒水问题 { //测试数据:三个水杯的大小 public static int a = 6, b = 3, c = 1; public static void main(String[] args) { //bfs算法初始化 LinkedList<State> list_backup = new LinkedList<State>(); LinkedList<State> list = new LinkedList<State>(); //测试数据:初始化 State State = new State(a, 0, 0); list.add(State); int count = 0; // bfs算法开始 while (list.size() > 0) { State ts = list.removeFirst(); int ta = ts.getBig(); int tb = ts.getMid(); int tc = ts.getLittle(); if (ta == 4) {//最终目标为4 count++; } //计算当前状态可能产生的所有下一状态,总数等于排列组合中A(3,2)=6 if (ta > 0 && tb < b) { State add1 = new State(ta - (b - tb), b, tc); if (!judge(list_backup, add1)) { list.addLast(add1); } } if (ta > 0 && tc < c) { State add2 = new State(ta - (c - tc), tb, c); if (!judge(list_backup, add2)) { list.addLast(add2); } } if (tb > 0 && tc < c) { State add3 = new State(ta, tb - (c - tc), c); if (!judge(list_backup, add3)) { list.addLast(add3); } } if (tb > 0 && ta < a) { State add4 = new State(ta + tb, 0, tc); if (!judge(list_backup, add4)) { list.addLast(add4); } } if (tc > 0 && ta < a) { State add5 = new State(ta + tc, tb, 0); if (!judge(list_backup, add5)) { list.addLast(add5); } } if (tc > 0 && tb < b) { State add6 = null; if (tc <= (b - tb)) { add6 = new State(ta, tb + tc, 0); } else { add6 = new State(ta, b, tc - (b - tb)); } if (!judge(list_backup, add6)) { list.addLast(add6); } } } System.out.println(count); } /** * 判断当前状态是否访问过 * * @param list 存放已经访问的状态 * @param add 当前状态 * @return */ public static boolean judge(LinkedList<State> list, State add) { boolean vis = false;// 没有访问 for (Iterator iterator = list.iterator(); iterator.hasNext(); ) { State comp = (State) iterator.next(); if (comp.getBig() == add.getBig() && comp.getMid() == add.getMid() && comp.getLittle() == add.getLittle()) { vis = true; break; } } if (!vis) { list.add(add); } return vis; } } /** * 将三个水桶中水的数量抽象为一个类 */ class State { //大桶中水的数目 private Integer big; //中桶中水的数目 private Integer mid; //小桶中水的数目 private Integer little; public State() { } public State(Integer big, Integer mid, Integer little) { super(); this.big = big; this.mid = mid; this.little = little; } public Integer getBig() { return big; } public void setBig(Integer big) { this.big = big; } public Integer getMid() { return mid; } public void setMid(Integer mid) { this.mid = mid; } public Integer getLittle() { return little; } public void setLittle(Integer little) { this.little = little; } }