/* 算法竞赛入门经典 例题 7-3 倒水问题 */
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
class Detail {// 各杯子目前储水量
int A, B, C;
public Detail(int a, int b, int c) {
A = a;
B = b;
C = c;
}
}
class FNode {// 目前状态
int[] state = new int[3];// 当前各杯子储水状态
int count;// 统计步数
LinkedList<Detail> process = new LinkedList<Detail>();// 记录产生过程
FNode createNewNode() {// 由当前状态产生一种下一个状态 需保留当前的值
FNode fd = new FNode();
for (int i = 0; i < 3; i++)
fd.state[i] = this.state[i];
fd.count = this.count;
fd.process = new LinkedList<Detail>(this.process);
return fd;
}
}
public class FillWater {
static final int MAX = 1000;
static int[][] vis = new int[MAX][MAX];// 标记状态是否产生过
static int x;
static int[] cups = new int[3];
static LinkedList<FNode> queue = new LinkedList<FNode>();
static FNode fd = new FNode();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while ((cups[0] = scanner.nextInt()) > 0) {
cups[1] = scanner.nextInt();
cups[2] = scanner.nextInt();
x = scanner.nextInt();
queue.clear();
for (int i = 0; i < MAX; i++)
Arrays.fill(vis[i], 0);
bfs();
}
}
private static boolean isFound(FNode fd) {
if (fd.state[0] == x || fd.state[1] == x || fd.state[2] == x)
return true;
return false;
}
private static void bfs() {
fd.state[0] = cups[0];
fd.state[1] = fd.state[2] = 0;
queue.offer(fd);
while (queue.size() > 0) {
fd = queue.poll();
vis[fd.state[0]][fd.state[1]] = 1;
if (isFound(fd)) {// 找到答案
System.out.println("需要步数:" + fd.count);
System.out.println(cups[0] + ",0" + ",0");
for (int i = 0; i < fd.process.size(); i++) {
Detail d = fd.process.get(i);
System.out.println(d.A + "," + d.B + "," + d.C);
}
return;
}
for (int i = 0; i < 3; i++) {// 尝试各种状态 从i向j倒水
if (fd.state[i] == 0)
continue;
for (int j = 0; j < 3; j++) {
if (j == i)
continue;
int water = cups[j] - fd.state[j];// 需要倒入的水量
if (water > 0) {// 计算实际倒入的水量
water = fd.state[i] > water ? water : fd.state[i];
fd.state[i] -= water;// 试产生新状态
fd.state[j] += water;
boolean flag = true;
if (vis[fd.state[0]][fd.state[1]] == 1) {//新产生状态已经生成过就恢复
fd.state[i] += water;
fd.state[j] -= water;
flag = false;
continue;
}
if (flag) {// 确定产生新状态 恢复当前状态 产生新状态
fd.state[i] += water;
fd.state[j] -= water;
FNode newNode = fd.createNewNode();
newNode.state[i] -= water;
newNode.state[j] += water;
Detail d = new Detail(newNode.state[0],
newNode.state[1], newNode.state[2]);
newNode.process.offer(d);
newNode.count++;
queue.offer(newNode);
}
}
}
}
}
}
}
测试用例
6 3 1 4
199 97 96 62