感 : 经典的倒水问题,个人很喜欢的一道 bfs. 另外 : 今天知识 地址作为参数只能用指针来接收!否则编译错误。
代码 : 为没有记录路径的 STL queue 的实现! 记录路径可以用 dfs , 状态中记录上一个节点地址,但是需要静态开辟状态,间接说明此时不能用 STL的queue记录了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 105;
struct Node {
int k1, k2, steps;
};
int vis[N][N];
string str[10] = { "FILL(1)", "DROP(1)", "FILL(2)", "DROP(2)", "POUR(1,2)", "POUR(2,1)" };
Node cur, nex;
int A, B, C;
void bfs(int v1, int v2) {
queue<Node> Q; // Don't put it in the global.
cur.k1 = v1; cur.k2 = v2; cur.steps = 0;
vis[0][0] = 1;
Q.push(cur);
while(!Q.empty()) {
Node top = Q.front();
Q.pop();
if(top.k1 == C || top.k2 == C) {
printf("%d\n", top.steps);
return;
}
int yi = 0;
for(int i = 0; i < 6; i++) {
switch(i) {
case 0 : nex.k1 = A, nex.k2 = top.k2; break;
case 1 : nex.k1 = 0, nex.k2 = top.k2; break;
case 2 : nex.k1 = top.k1; nex.k2 = B; break;
case 3 : nex.k1 = top.k1; nex.k2 = 0; break;
case 4 :
yi = top.k1 + top.k2 - B;
if(yi > 0) {
nex.k2 = B;
nex.k1 = yi;
}
else {
nex.k1 = 0;
nex.k2 = top.k1 + top.k2;
}
break;
case 5 :
yi = top.k1 + top.k2 - A;
if(yi > 0) {
nex.k1 = A;
nex.k2 = yi;
}
else {
nex.k1 = top.k1 + top.k2;
nex.k2 = 0;
}
break;
}
if(!vis[nex.k1][nex.k2]) {
nex.steps = top.steps + 1;
Q.push(nex);
vis[nex.k1][nex.k2] = 1;
}
}
}
cout << "impossble" << endl;
}
int main() {
while(scanf("%d%d%d", &A, &B, &C) == 3) {
memset(vis, 0, sizeof(vis));
bfs(0, 0);
}
return 0;
}