HDU_1495(BFS)
BFS:
- 剪枝:奇数可乐肯定不能被平分
- 枚举6种操作
a->c
a->b
b->a
b->c
c->a
c->b
- 将每个杯子有多少可乐作为状态保存下来
- 在
a == b && c == 0
或者a == c && b == 0
或者b == c && a == 0
时则平分成功, - 或者我们可以规定b是小杯子,c是大杯子,这样到最后肯定,平分到了b,c中,反过来规定也行
即:bfs:1
2
3
4
5
6
7
8
9
10// 规定
if (n[2] > n[3]) { // 规定 b 杯子比 c杯子小,
swap(n[2],n[3]);
}
// 退出状态
if (cur.v[1] == cur.v[3] && cur.v[2] == 0) { // 平分了,装在两2大杯子中
printf("%d\n",cur.step);
return ;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85#include <queue>
#include <iostream>
#include <string.h>
using namespace std;
int n[4];
int vis[102][102][102];
struct cup{
int v[4];
int step;
cup(){}
cup(int a,int b,int c,int s){
v[1] = a;
v[2] = b;
v[3] = c;
step = s;
}
};
void pour(int a,int b,cup* t) { // 杯子a的可乐倒进杯子b
int sum = t->v[a] + t->v[b];
if (sum >= n[b]) // 超出了b杯子的容量
t->v[b] = n[b]; // 只能到把杯子倒满,剩下的不倒
else
t->v[b] = sum;
t->v[a] = sum - t->v[b]; // 原来a,b,的总量,减去现在b的总量
}
void bfs() {
// 剪枝
if (n[1] % 2) {
printf("NO\n");
return ;
}
queue<cup> que;
memset(vis,0,sizeof vis);
que.push( cup(n[1],0,0,0) );
vis[n[1]][0][0] = 1;
while ( !que.empty() ) {
cup cur = que.front();
que.pop();
if (cur.v[1] == cur.v[3] && cur.v[2] == 0) { // 平分了,装在两2大杯子中
printf("%d\n",cur.step);
return ;
} else if (cur.v[1] == cur.v[2] && cur.v[3] == 0) {
printf("%d\n",cur.step);
return ;
}
else if (cur.v[2] == cur.v[3] && cur.v[1] == 0) {
printf("%d\n",cur.step);
return ;
}
for (int i=1; i<4; i++) { // 枚举6种 倒 法
for (int j=1; j<4; j++) {
if (i != j) { // 每个杯子倒水2中选择,不到给自己就行了
cup temp = cur;
pour(i,j,&temp);
if( !vis[temp.v[1]][temp.v[2] ][temp.v[3]] ) {
vis[temp.v[1]][temp.v[2]][temp.v[3]] = 1;
temp.step += 1;
que.push( temp );
}
}
}
}
}
printf("NO\n");
return ;
}
int main() {
// freopen("a.txt","r",stdin);
while (scanf("%d%d%d",&n[1],&n[2],&n[3]) && n[1]) {
// if (n[2] > n[3]) { // 规定 b 杯子比 c杯子小,
// swap(n[2],n[3]);
// }
bfs();
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!