Ranking (as of 2013-06-15): 670 out of 1520
Language: C++
/* UVa 571 - Jugs To build using Visual Studio 2008: cl -EHsc -O2 jugs.cpp */ #include <iostream> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; enum {fill_A, fill_B, empty_A, empty_B, pour_A_B, pour_B_A}; struct jugs { int a_, b_; stack<char> steps_; jugs(int a, int b, char s) : a_(a), b_(b) {steps_.push(s);} jugs(int a, int b, char s, const stack<char>& steps) : a_(a), b_(b), steps_(steps) {steps_.push(s);} }; void print_steps(stack<char>& steps) { const char* instructions[] = {"fill A\n", "fill B\n", "empty A\n", "empty B\n", "pour A B\n", "pour B A\n"}; if (!steps.empty()) { char s = steps.top(); steps.pop(); print_steps(steps); cout << instructions[s]; } } bool push_jugs_state(int a, int b, char s, const stack<char>& steps, vector< vector<bool> >& states, queue<jugs>& q) { if (!states[a][b]) { states[a][b] = true; q.push(jugs(a, b, s, steps)); return true; } else return false; // do not transfer to the state that has already been transferred before } void pour_jugs(int ca, int cb, int n) { vector< vector<bool> > states(ca + 1, vector<bool>(cb + 1, false)); // states[i][j] is true if the state where the content of A is i and // the content of B is j has already been examined queue<jugs> q; if (ca > n) { states[ca][0] = true; q.push(jugs(ca, 0, fill_A)); } else { states[0][cb] = true; q.push(jugs(0, cb, fill_B)); } for ( ; !q.empty(); q.pop()) { jugs& j = q.front(); if (j.b_ == n) { print_steps(j.steps_); break; } int a, b, p; // if either of the jugs is empty, try pouring to the empty jug, // or fill the empty jug if (!j.a_) { p = min(ca, j.b_); push_jugs_state(p, j.b_ - p, pour_B_A, j.steps_, states, q); if (j.b_ < cb) push_jugs_state(ca, j.b_, fill_A, j.steps_, states, q); } else if (!j.b_) { p = min(j.a_, cb); push_jugs_state(j.a_ - p, p, pour_A_B, j.steps_, states, q); if (j.a_ < ca) push_jugs_state(j.a_, cb, fill_B, j.steps_, states, q); } // if both of the jugs are not empty, try pouring between jags, // or empty the fully-filled jug else { if (j.a_ < ca) { p = min(ca - j.a_, j.b_); push_jugs_state(j.a_ + p, j.b_ - p, pour_B_A, j.steps_, states, q); } else if (j.a_ == ca) push_jugs_state(0, j.b_, empty_A, j.steps_, states, q); if (j.b_ < cb) { p = min(cb - j.b_, j.a_); push_jugs_state(j.a_ - p, j.b_ + p, pour_A_B, j.steps_, states, q); } else if (cb == j.b_) push_jugs_state(j.a_, 0, empty_B, j.steps_, states, q); } } cout << "success\n"; } int main() { int ca, cb, n; while (cin >> ca >> cb >> n) pour_jugs(ca, cb, n); return 0; }
No comments:
Post a Comment