-
Notifications
You must be signed in to change notification settings - Fork 0
/
WaterTrack.java
152 lines (133 loc) · 2.64 KB
/
WaterTrack.java
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//深度优先搜索,递归
// 2014-10-24
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
public class WaterTrack {
int CA = 11; // 两个桶的容量
int CB = 4;
int dest = 3; // 目标
// 6个操作
String opName[] = { "装满A桶 ", "装满B桶 ", "清空A桶 ", "清空B桶 ",
"A中水倒入B", "B中水倒入A", };
// 结点
class Node {
int qa = 0;
int qb = 0;
@Override
public int hashCode() {
int ret = qa * 1024 + qb;
return ret;
}
@Override
public boolean equals(Object n) {
Node nd = (Node) n;
return nd.qa == qa && nd.qb == qb;
}
}
// 带路径的结点
class PathNode extends Node {
List<Integer> path = new ArrayList<Integer>();
}
PathNode pnResult;
// 已访问结点
Set<Node> visited = new HashSet<Node>();
// 根据操作码进行操作
void operate(PathNode nd, int code) {
switch (code) {
case 0:
nd.qa = CA;
break;
case 1:
nd.qb = CB;
break;
case 2:
nd.qa = 0;
break;
case 3:
nd.qb = 0;
break;
case 4:
if (nd.qa <= CB - nd.qb) {
nd.qb += nd.qa;
nd.qa = 0;
} else {
nd.qa -= CB - nd.qb;
nd.qb = CB;
}
break;
case 5:
if (nd.qb <= CA - nd.qa) {
nd.qa += nd.qb;
nd.qb = 0;
} else {
nd.qb -= CA - nd.qa;
nd.qa = CA;
}
break;
}
nd.path.add(code);
}
// 成功
boolean success(Node nd) {
return nd.qa == dest || nd.qb == dest
|| (dest > nd.qa && dest > nd.qb && dest == nd.qa + nd.qb);
}
// 已访问
boolean visited(Node nd) {
return visited.contains(nd);
}
void searchTrack(PathNode pn) {
if (pnResult != null) {
return;
} else if (success(pn)) {
pnResult = pn;
return;
} else {
for (int i = 0; i <= 5; i++) {
PathNode pnNew = new PathNode();
pnNew.qa = pn.qa;
pnNew.qb = pn.qb;
pnNew.path.addAll(pn.path);
operate(pnNew, i);
if (!visited(pnNew)){
visited.add(pnNew);
searchTrack(pnNew);
}
}
}
}
void search() {
PathNode pn = new PathNode();
visited.add(pn);
searchTrack(pn);
if (pnResult != null) {
print(pnResult);
} else {
System.out.println("无解");
}
}
void print(PathNode pn) {
PathNode pathResult = new PathNode();
for (Integer i : pn.path) {
this.operate(pathResult, i);
System.out.println(opName[i] + "\t\t\t--->" + pathResult.qa + ' '
+ pathResult.qb);
}
}
void input() {
System.out.println("依次输入A B桶的容量和目标水量,如6 5 3");
Scanner sc = new Scanner(System.in);
CA = sc.nextInt();
CB = sc.nextInt();
dest = sc.nextInt();
sc.close();
}
public static void main(String args[]) {
WaterTrack w = new WaterTrack();
w.input();
w.search();
}
}