G - 非常可乐--重复广搜

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
Sample Input
7 4 3
4 1 3
0 0 0
Sample Output
NO

3

分析:这道题最终的状态就是三个里面只要有两个体积相等同时另一个为零即可,那么由于可能性很多并且步数繁杂,采用广搜是比较好的方法,虽然代码量大,但是基本思路都是重复的,大致思路就是把六种状态都遍历一遍就好了

import java.util.*;

public class Main {

	static Scanner in = new Scanner(System.in);

	static final int maxn = 105;
	//标志数组来标记路径,三个杯子三维数组即可
	static int[][][] visited = new int[maxn][maxn][maxn];

	static void init() {
		for (int i = 0; i < maxn; ++i)
			for (int j = 0; j < maxn; ++j)
				for (int k = 0; k < maxn; ++k)
					visited[i][j][k] = 0;
	}

	// a b c为三个容器的最大容量
	static void bfs(int a, int b, int c) {
		if (a % 2 == 1) {
			System.out.println("NO");
			return;
		}
		Queue<Node> que = new LinkedList<Node>();
		// 初始
		que.add(new Node(a, 0, 0, 0));
		while (!que.isEmpty()) {
			// 取队头并弹出
			Node t = que.poll();
			visited[t.a][t.b][t.c] = 1;
			// 判断是否符合条件
			if (t.a == t.b && t.c == 0 || t.a == t.c && t.b == 0 || t.b == t.c && t.a == 0) {
				System.out.println(t.step);
				return;
			}

			// 倒水过程,注意倒水的前提是杯子里面有水
			// b -> a
			if (t.b != 0) {
				// 因为没有刻度, 所以每次倒水都有两种情况
				// 第一种情况是把自己倒完
				if (t.a + t.b <= a) {
					if (visited[t.a + t.b][0][t.c] == 0) {
						que.add(new Node(t.a + t.b, 0, t.c, t.step + 1));
						visited[t.a + t.b][0][t.c] = 1;
					}
				}
				// 第二种情况是把对方倒满
				else if (t.a != a) {
					if (visited[a][t.b - (a - t.a)][t.c] == 0) {
						que.add(new Node(a, t.b - (a - t.a), t.c, t.step + 1));
						visited[a][t.b - (a - t.a)][t.c] = 1;
					}
				}
			}

			// c -> a
			if (t.c != 0) {
				if (t.a + t.c <= a) {
					if (visited[t.a + t.c][t.b][0] == 0) {
						que.add(new Node(t.a + t.c, t.b, 0, t.step + 1));
						visited[t.a + t.c][t.b][0] = 1;
					}
				} else if (t.a != a) {
					if (visited[a][t.b][t.c - (a - t.a)] == 0) {
						que.add(new Node(a, t.b, t.c - (a - t.a), t.step + 1));
						visited[a][t.b][t.c - (a - t.a)] = 1;
					}
				}
			}

			// b -> c
			if (t.b != 0) {
				if (t.b + t.c <= c) {
					if (visited[t.a][0][t.b + t.c] == 0) {
						que.add(new Node(t.a, 0, t.b + t.c, t.step + 1));
						visited[t.a][0][t.b + t.c] = 1;
					}
				} else if (t.c != c) {
					if (visited[t.a][t.b - (c - t.c)][c] == 0) {
						que.add(new Node(t.a, t.b - (c - t.c), c, t.step + 1));
						visited[t.a][t.b - (c - t.c)][c] = 1;
					}
				}
			}

			// c -> b
			if (t.c != 0) {
				if (t.c + t.b <= b) {
					if (visited[t.a][t.c + t.b][0] == 0) {
						que.add(new Node(t.a, t.c + t.b, 0, t.step + 1));
						visited[t.a][t.c + t.b][0] = 1;
					}
				} else if (t.b != b) {
					if (visited[t.a][b][t.c - (b - t.b)] == 0) {
						que.add(new Node(t.a, b, t.c - (b - t.b), t.step + 1));
						visited[t.a][b][t.c - (b - t.b)] = 1;
					}
				}
			}

			// a -> b
			if (t.a != 0) {
				if (t.a + t.b <= b) {
					if (visited[0][t.a + t.b][t.c] == 0) {
						que.add(new Node(0, t.a + t.b, t.c, t.step + 1));
						visited[0][t.a + t.b][t.c] = 1;
					}
				} else if (t.b != b) {
					if (visited[t.a - (b - t.b)][b][t.c] == 0) {
						que.add(new Node(t.a - (b - t.b), b, t.c, t.step + 1));
						visited[t.a - (b - t.b)][b][t.c] = 1;
					}
				}
			}

			// a -> c
			if (t.a != 0) {
				if (t.a + t.c <= c) {
					if (visited[0][t.b][t.a + t.c] == 0) {
						que.add(new Node(0, t.b, t.a + t.c, t.step + 1));
						visited[0][t.b][t.a + t.c] = 1;
					}
				} else if (t.c != c) {
					if (visited[t.a - (c - t.c)][t.b][c] == 0) {
						que.add(new Node(t.a - (c - t.c), t.b, c, t.step + 1));
						visited[t.a - (c - t.c)][t.b][c] = 1;
					}
				}
			}

		}
		System.out.println("NO");
	}

	public static void main(String[] args) {

		while (in.hasNext()) {
			int a = in.nextInt(), b = in.nextInt(), c = in.nextInt();
			if (a == 0 && b == 0 && c == 0)
				break;
			init();
			bfs(a, b, c);
		}
	}

}

class Node {
	// a b c 代表实际拥有水的体积
	int a, b, c, step;

	Node(int a, int b, int c, int step) {
		this.a = a;
		this.b = b;
		this.c = c;
		this.step = step;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值