又是深度优先搜索,枚举,为了不出现无限循环,为了所出现的每种状态(三个杯子现有milk数)仅考虑一次,使用isAppeared变量来记录某种状态是否已经出现过。

Code

/**//*
ID: sdjllyh1
PROG: milk3
LANG: JAVA
complete date: 2008/11/22
author: LiuYongHui From GuiZhou University Of China
more article: www.cnblogs.com/sdjls
*/

import java.io.*;
import java.util.*;

public class milk3


{
private static Cup[] cup = new Cup[3];
private static ArrayList answers = new ArrayList();
private static boolean[][][] isAppeared;//记录某种状态是否出现过,避免没有必要的递归搜索
public static void main(String[] args) throws IOException

{
init();
run();
output();
System.exit(0);
}

private static void run()

{
//一开始,把c往a里到
dfs_pour(cup[2], cup[0]);
//还原为初始状态
cup[0].existing = 0;
cup[1].existing = 0;
cup[2].existing = cup[2].capacity;
//把c往b里到
dfs_pour(cup[2], cup[1]);
//按照杯子里拥有的milk数进行排序
Collections.sort(answers);
}

//把firstCup里的milk往secondCup里到,然后进行深度优先搜索
private static void dfs_pour(Cup firstCup, Cup secondCup)

{
firstCup.pour(secondCup);
//如果这个状态出现过则退出递归,不再考虑
if (isAppeared[cup[0].existing][cup[1].existing][cup[2].existing])

{
return;
}
else

{
//标记已经出现过此状态
isAppeared[cup[0].existing][cup[1].existing][cup[2].existing] = true;
if (cup[0].existing==0)

{
answers.add(cup[2].cloneCup());
}
//给当前杯子状态做个备份
Cup[] backupCup = new Cup[3];
backupCup[0] = cup[0].cloneCup();
backupCup[1] = cup[1].cloneCup();
backupCup[2] = cup[2].cloneCup();

//以下尝试6种不同的倾倒方式
dfs_pour(cup[0], cup[1]);
cup[0] = backupCup[0].cloneCup();
cup[1] = backupCup[1].cloneCup();
cup[2] = backupCup[2].cloneCup();

dfs_pour(cup[0], cup[2]);
cup[0] = backupCup[0].cloneCup();
cup[1] = backupCup[1].cloneCup();
cup[2] = backupCup[2].cloneCup();

dfs_pour(cup[1], cup[0]);
cup[0] = backupCup[0].cloneCup();
cup[1] = backupCup[1].cloneCup();
cup[2] = backupCup[2].cloneCup();

dfs_pour(cup[1], cup[2]);
cup[0] = backupCup[0].cloneCup();
cup[1] = backupCup[1].cloneCup();
cup[2] = backupCup[2].cloneCup();

dfs_pour(cup[2], cup[0]);
cup[0] = backupCup[0].cloneCup();
cup[1] = backupCup[1].cloneCup();
cup[2] = backupCup[2].cloneCup();

dfs_pour(cup[2], cup[1]);
cup[0] = backupCup[0].cloneCup();
cup[1] = backupCup[1].cloneCup();
cup[2] = backupCup[2].cloneCup();
}
}

private static void init() throws IOException

{
BufferedReader f = new BufferedReader(new FileReader("milk3.in"));
StringTokenizer st = new StringTokenizer(f.readLine());
int capacityA = Integer.parseInt(st.nextToken());
int capacityB = Integer.parseInt(st.nextToken());
int capacityC = Integer.parseInt(st.nextToken());
f.close();
cup[0] = new Cup(capacityA, 0);
cup[1] = new Cup(capacityB, 0);
cup[2] = new Cup(capacityC, capacityC);
isAppeared = new boolean[capacityA+1][capacityB + 1][capacityC+1];
}

private static void output() throws IOException

{
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("milk3.out")));
Iterator it = answers.iterator();
Cup c = (Cup)it.next();
out.print(c.existing);
int lastExisting = c.existing;//使用lastExisting是为了避免输出相同的答案
while (it.hasNext())

{
c = (Cup)it.next();
if (lastExisting != c.existing)

{
out.print(" " + c.existing);
lastExisting = c.existing;
}
}
out.println();
out.close();
}
}

//杯子类
class Cup implements Comparable


{
public int capacity;//杯子的容量
public int existing;//杯子当前拥有的milk数
public Cup(int capacity,int existing)

{
this.capacity = capacity;
this.existing = existing;
}
//向另一个杯子中倾倒milk
public void pour(Cup aim)

{
if (this.existing >= aim.capacity - aim.existing)

{
this.existing -= aim.capacity - aim.existing;
aim.existing = aim.capacity;
}
else

{
aim.existing += this.existing;
this.existing = 0;
}
}
//获得杯子的一个备份
public Cup cloneCup()

{
return new Cup(this.capacity, this.existing);
}
//为了排序existing,以便输出,而实现的
public int compareTo(Object arg0)

{
Cup compareCup = (Cup)arg0;
if (this.existing > compareCup.existing)

{
return 1;
}
else if (this.existing < compareCup.existing)

{
return -1;
}
else

{
return 0;
}
}
}