这题是倒水问题啊,为什么那么多人用深搜呢不懂。
题目概述:
题目大概是说有ABC三个水桶,最开始的时候C是满的,其他都空,然后我我们的各种操作就是互相倒来倒去,每一次都倒到不能倒为止(被倒的满了或者是倒的空了)。但是不会有水溢出来,计算当A是空的时候,C中所有可能出现的水量。
算法思想:
因为我第一眼看和POJ3414十分相似,我就直接用广搜做了。数据量范围才到20,于是我大概就是开一个三维数组记录状态是否出现过,并且开一个数组单独记录C中的可能满足题目要求的状态。
然后用 stl::queue 来放置各种状态,具体一个状态用结构体来记录。如果状态没有出现过就放到queue里面,如果此时A还是空的就记录在单独的数组里面。
具体实现可看代码。
题解中很多人用深搜,当然是可以的,不过不知道为什么会想到深搜。
代码部分:
#include <iostream> #include <list> #include <map> #include <queue> #include <math.h> #include <string.h> #include <string> #include <fstream> #include <algorithm> using namespace std; ifstream fin("milk3.in"); ofstream fout("milk3.out"); int n, up_bound; int res[22][22][22]; int fi[22]; struct node { int a, b, c; node(int a_m, int b_m, int c_m) : a(a_m), b(b_m), c(c_m) {} }; int main() { int A, B, C; fin >> A >> B >> C; queue<node> q; node n(0, 0, C); res[0][0][C] = 1; fi[C] = 1; q.push(n); while (!q.empty()) { node tmp = q.front(); q.pop(); // pour c to a if (tmp.c != 0 && tmp.a != A) { if (tmp.c <= A - tmp.a) { node t(tmp.a + tmp.c, tmp.b, 0); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } else { node t(A, tmp.b, tmp.c - A + tmp.a); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } } // pour c to b if (tmp.c != 0 && tmp.b != B) { if (tmp.c <= B - tmp.b) { node t(tmp.a, tmp.b + tmp.c, 0); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } else { node t(tmp.a, B, tmp.c - B + tmp.b); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } } // pour a to b if (tmp.a != 0 && tmp.b != B) { if (tmp.a <= B - tmp.b) { node t(0, tmp.b + tmp.a, tmp.c); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } else { node t(tmp.a - B + tmp.b, B, tmp.c); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } } // pour a to c if (tmp.a != 0 && tmp.c != C) { if (tmp.a <= C - tmp.c) { node t(0, tmp.b, tmp.c + tmp.a); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } else { node t(tmp.a - C + tmp.c, tmp.b, C); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } } // pour b to a if (tmp.b != 0 && tmp.a != A) { if (tmp.b <= A - tmp.a) { node t(tmp.a + tmp.b, 0, tmp.c); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } else { node t(A, tmp.b - A + tmp.a, tmp.c); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } } // pour b to c if (tmp.b != 0 && tmp.c != C) { if (tmp.b <= C - tmp.c) { node t(tmp.a, 0, tmp.c + tmp.b); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } else { node t(tmp.a, tmp.b - C + tmp.c, C); if (res[t.a][t.b][t.c] == 0) { q.push(t); res[t.a][t.b][t.c] = 1; if (t.a == 0) { fi[t.c] = 1; } } } } } vector<int> v; for (int i = 0; i <= C; i++) { if (fi[i]) { v.push_back(i); } } for (int i = 0; i < v.size(); i++) { if (i == v.size() - 1) fout << v[i] << endl; else fout << v[i] << " "; } return 0; }