package search;
/*三个水杯
时间限制:1000 ms | 内存限制:65535 KB
描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。
三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。
现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数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
我的思路:这道题和我做的拿到泊松分酒感觉挺像的,但是我那样做,不能保证是最少次数的,然后又用深搜,不知道为什么一直内存益处;
最后实在不知道咋办,就找度娘,看了一大神(http://blog.csdn.net/jcjc918/article/details/9336785)的思路,然后我用java做出来了。用广搜。
首先杯子有三个:a , b ,c;
1,先将杯子a放进队列,在bfs()里,出队,那么a可以给b或者c倒水,那就分别都倒水
2,上一步完成之后,就将b和c的状态入队,同时用一个数组记录那个状态出现过了就为true
3,不断重复1,2步骤,直到队列为空为止,请看代码。
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.Arrays;
import java.util.LinkedList;
public class search_21 {
// 创建一个杯子类
public static class Cup {
int a, b, c, count;
public Cup() {
}
public Cup(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
}
private static int v1 = 0, v2 = 0, v3 = 0, e1 = 0, e2 = 0, e3 = 0;// 一开始输入的杯子体积和目标状态
private static LinkedList<Cup> cups = new LinkedList<Cup>();// 队列
private static boolean[][][] visited = new boolean[101][101][101];// 记录杯子出现过的状态
private static Cup start, cup;
private static boolean has;// 判断是否有可能达到目标状态
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
int n = sc.nextInt();
while (n-- > 0) {
// 这里是初始化,因为题目要求可一次同时测试多组数据
cups.clear();
for (int i = 0; i < 101; i++)
for (int j = 0; j < 101; j++)
Arrays.fill(visited[i][j], false);
has = false;
v1 = sc.nextInt();
v2 = sc.nextInt();
v3 = sc.nextInt();
e1 = sc.nextInt();
e2 = sc.nextInt();
e3 = sc.nextInt();
start = new Cup(v1, 0, 0);
visited[v1][0][0] = true;
cups.add(start);// 将初始状态入队
bfs();// 广搜
if (!has)
System.out.println(-1);
}
sc.close();
}
private static void bfs() {
while (!cups.isEmpty()) {
cup = cups.remove();// 出队
// System.out.println(cup.a + " " + cup.b + " " +
// cup.c);//打印过程
// 如果达到目标
if (cup.a == e1 && cup.b == e2 && cup.c == e3) {
System.out.println(cup.count);
has = true;
break;
}
// 如果杯子a有水,而杯子b的水没有符合目标要求,那么a倒水给b
if (cup.a != 0 && cup.b < v2) {
Cup tmp = new Cup();
// 如果a的水+b的水比b的水杯体积还大,那么a杯子有剩
if (cup.a + cup.b > v2)
tmp.a = cup.a + cup.b - v2;
else
tmp.a = 0;
// 那么b杯子有a倒过来的水( cup.a - tmp.a )+可能自己原本也有的水(cup.b)
tmp.b = cup.a - tmp.a + cup.b;
tmp.c = cup.c;
tmp.count = cup.count + 1;// 更新次数
// 标记状态
if (!visited[tmp.a][tmp.b][tmp.c]) {
visited[tmp.a][tmp.b][tmp.c] = true;
cups.add(tmp);
}
}
//下面一样的道理
//a→c
if (cup.a != 0 && cup.c < v3) {
Cup tmp = new Cup();
if (cup.a + cup.c > v3)
tmp.a = cup.a + cup.c - v3;
else
tmp.a = 0;
tmp.c = cup.a - tmp.a + cup.c;
tmp.b = cup.b;
tmp.count = cup.count + 1;
if (!visited[tmp.a][tmp.b][tmp.c]) {
visited[tmp.a][tmp.b][tmp.c] = true;
cups.add(tmp);
}
}
//b→a
if (cup.b != 0 && cup.a < v1) {
Cup tmp = new Cup();
if (cup.b + cup.a > v1)
tmp.b = cup.b + cup.a - v1;
else
tmp.b = 0;
tmp.a = cup.b - tmp.b + cup.a;
tmp.c = cup.c;
tmp.count = cup.count + 1;
if (!visited[tmp.a][tmp.b][tmp.c]) {
visited[tmp.a][tmp.b][tmp.c] = true;
cups.add(tmp);
}
}
//b→c
if (cup.b != 0 && cup.c < v3) {
Cup tmp = new Cup();
if (cup.b + cup.c > v3)
tmp.b = cup.b + cup.c - v3;
else
tmp.b = 0;
tmp.c = cup.b - tmp.b + cup.c;
tmp.a = cup.a;
tmp.count = cup.count + 1;
if (!visited[tmp.a][tmp.b][tmp.c]) {
visited[tmp.a][tmp.b][tmp.c] = true;
cups.add(tmp);
}
}
//c→a
if (cup.c != 0 && cup.a < v1) {
Cup tmp = new Cup();
if (cup.c + cup.a > v1)
tmp.c = cup.c + cup.a - v1;
else
tmp.c = 0;
tmp.a = cup.c - tmp.c + cup.a;
tmp.b = cup.b;
tmp.count = cup.count + 1;
if (!visited[tmp.a][tmp.b][tmp.c]) {
visited[tmp.a][tmp.b][tmp.c] = true;
cups.add(tmp);
}
}
//c→b
if (cup.c != 0 && cup.b < v2) {
Cup tmp = new Cup();
if (cup.c + cup.b > v2)
tmp.c = cup.c + cup.b - v2;
else
tmp.c = 0;
tmp.b = cup.c - tmp.c + cup.b;
tmp.a = cup.a;
tmp.count = cup.count + 1;
if (!visited[tmp.a][tmp.b][tmp.c]) {
visited[tmp.a][tmp.b][tmp.c] = true;
cups.add(tmp);
}
}
}
}
}
NYOJ--21(搜索)-题目-----------------------------三个水杯
最新推荐文章于 2019-10-09 14:40:17 发布