感 : 经典的倒水问题,个人很喜欢的一道 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;
}