算法竞赛入门经典 例题7-3 倒水问题

/* 算法竞赛入门经典 例题 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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值