三个水杯
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
-
输入
-
第一行一个整数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
来源
本题主要是用BFS搜索各种情况,用队列存贮状态,直到搜到所要答案。以后这种情况很多的类型,相互变换的都可以用BFS尝试下。
分清楚六中状态,1~2,1~3,2~3,3~2,3~1,3~2,然后用广度搜索就行。
其实也是暴利破解,穷举所有情况,找到的话就返回步数,否则返回-1。
下面只提供一个参考,还有许多事情要解决呢~这次的房租交的有些非常水啊~~~
S:
#include<stdio.h> #include<string.h> int v1, v2, v3, e1, e2, e3; typedef struct { int a,b,c,n; }node; node q[1100000]; int min=-1; void bfs(int a, int b, int c, int n) { int i, j, d[2][3] = {v1, v2, v3, a, b, c}, ok, k; for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { ok=0; if(i != j && d[1][i] != 0 && d[1][j] != d[0][j]) { if(d[0][j] - d[1][j] >= d[1][i]) { d[1][j] += d[1][i]; d[1][i] = 0; ok = 1; } else { d[1][i] -= d[0][j] - d[1][j]; d[1][j] = d[0][j]; ok = 1; } } if (ok) for(k = 0; q[k].a + q[k].b + q[k].c != 0; k++) if(q[k].a == d[1][0] && q[k].b == d[1][1] && q[k].c == d[1][2]) ok = 0; if(ok) { q[k].a = d[1][0]; q[k].b = d[1][1]; q[k].c = d[1][2]; q[k].n = n+1; if(q[k].a == e1 && q[k].b == e2 && q[k].c == e3) min = q[k].n; } if(min != -1) break; d[1][0] = a; d[1][1] = b; d[1][2] = c; } if(min != -1) break; } } int main() { int N; int i; scanf("%d", &N); while(N--) { memset(q, 0, sizeof(q)); scanf("%d%d%d%d%d%d", &v1, &v2, &v3, &e1, &e2, &e3); q[0].a = v1; q[0].b = 0; q[0].c = 0; q[0].n = 0; i = 0; if(e1 == v1 && e2 == 0 && e3 == 0) min = 0; else { while(q[i].a + q[i].b + q[i].c != 0) { bfs(q[i].a, q[i].b, q[i].c, q[i].n); if(min != -1) break; i++; } } printf("%d\n", min); min = -1; } return 0; }
-
第一行一个整数N(0<N<50)表示N组测试数据