三个水杯
时间限制:
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
-
-
01.
/*
02.
*@author doctoroyy
03.
*@param V[3] 水杯容量
04.
*@param E[3] 水杯目标状态
05.
*@param vis[maxn][maxn][maxn] 节点访问状态
06.
*@param node 包括三只水杯,倒水次数
07.
*@param bottle 包含容量、当前水量
08.
*/
09.
#include<iostream>
10.
#include<queue>
11.
#include<cstring>
12.
#include<cstdio>
13.
using
namespace
std;
14.
const
int
maxn = 100;
15.
int
vis[maxn][maxn][maxn];
16.
int
V[3], E[3];
17.
struct
bottle {
18.
int
capacity;
19.
int
water;
20.
};
21.
struct
node {
22.
bottle b[3];
23.
int
step;
24.
};
25.
//模拟倒水(水杯i往水杯j倒水)
26.
int
pour(
int
i,
int
j, node &head) {
27.
if
(head.b[i].water > 0 && head.b[j].water < head.b[j].capacity) {
28.
if
(head.b[i].water <= head.b[j].capacity - head.b[j].water) {
29.
head.b[j].water += head.b[i].water;
30.
head.b[i].water = 0;
31.
}
else
{
32.
head.b[i].water -= head.b[j].capacity - head.b[j].water;
33.
head.b[j].water = head.b[j].capacity;
34.
}
35.
return
1;
// 倒水成功返回状态 1
36.
}
37.
return
0;
38.
}
39.
int
bfs() {
40.
queue <node> q;
41.
node root;
42.
for
(
int
i = 0; i < 3; i++) {
43.
root.b[i].capacity = V[i];
44.
root.b[i].water = 0;
45.
}
46.
root.b[0].water = V[0];
47.
root.step = 0;
48.
q.push(root);
49.
vis[root.b[0].water][root.b[1].water][root.b[2].water] = 1;
50.
while
(!q.empty()) {
51.
node head = q.front();
52.
q.pop();
53.
if
(head.b[0].water == E[0] && head.b[1].water == E[1] && head.b[2].water == E[2]) {
54.
return
head.step;
55.
}
56.
for
(
int
i = 0; i < 2; i++) {
57.
for
(
int
j = 1; j < 3; j++) {
58.
if
(i == j)
continue
;
59.
node h1 = head, h2 = head;
60.
if
(pour(i, j, h1)) {
61.
if
(!vis[h1.b[0].water][h1.b[1].water][h1.b[2].water]) {
62.
h1.step = head.step + 1;
63.
q.push(h1);
64.
vis[h1.b[0].water][h1.b[1].water][h1.b[2].water] = 1;
65.
}
66.
}
67.
if
(pour(j, i, h2)) {
68.
if
(!vis[h2.b[0].water][h2.b[1].water][h2.b[2].water]) {
69.
h2.step = head.step + 1;
70.
q.push(h2);
71.
vis[h2.b[0].water][h2.b[1].water][h2.b[2].water] = 1;
72.
}
73.
}
74.
}
75.
}
76.
}
77.
return
-1;
78.
}
79.
int
main() {
80.
int
t;
81.
scanf
(
"%d"
, &t);
82.
while
(t--) {
83.
memset
(vis, 0,
sizeof
(vis));
84.
for
(
int
i = 0; i < 3; i++)
scanf
(
"%d"
, &V[i]);
85.
for
(
int
j = 0; j < 3; j++)
scanf
(
"%d"
, &E[j]);
86.
printf
(
"%d\n"
, bfs());
87.
}
88.
}