#include <iostream> #include <algorithm> #include <unordered_set> #include <deque> using namespace std; struct state { int volume[3], step; void find_to_add(int& deg, state (&to_add)[6]); bool operator==(const state &other) const { return (volume[0] == other.volume[0] && volume[1] == other.volume[1] && volume[2] == other.volume[2] && step == other.step); } void print() { cout << "state "; for (int i=0; i<3; i++) cout << volume[i] << ' '; cout << ", step " << step << '\n'; } }; int A, B, C, a, b, c; long long res[100007]; state max_capasity; void state::find_to_add(int& deg, state (&to_add)[6]) { deg = 0; for (int i=0; i<3; i++) for (int j=0; j<3; j++) if (i!=j) { // moving from i to j int to_move = min(this->volume[i], max_capasity.volume[j] - this->volume[j]); if (to_move > 0) { state new_state; copy(this->volume, this->volume+3, new_state.volume); new_state.step = 0; new_state.volume[i] -= to_move; new_state.volume[j] += to_move; to_add[deg] = new_state; deg ++; } } return; } struct StateHasher { size_t operator()(const state& my_state) const { size_t ans=0; for (int i=0; i<3; i++) { ans *= 100007; ans += my_state.volume[i]; } return ans; } }; int main() { ios_base::sync_with_stdio(0); cin >> max_capasity.volume[0] >> max_capasity.volume[1] >> max_capasity.volume[2]; cin >> a >> b >> c; state start_capasity {a, b, c, 0}; for (int i=0; i<max_capasity.volume[2]+1; i++) res[i] = -1; int seen_values = 0; int max_value = start_capasity.volume[0] + start_capasity.volume[1] + start_capasity.volume[2]; deque<state> my_que; my_que.push_back(start_capasity); unordered_set<state, StateHasher> seen_states; seen_states.reserve(3*C+7); seen_states.insert(start_capasity); while (not my_que.empty() && (seen_values < max_value + 1)) { state current_state = my_que.front(); // cout << "visiting "; current_state.print(); my_que.pop_front(); for (int i=0; i<3; i++) if (res[current_state.volume[i]] == -1) { res[current_state.volume[i]] = current_state.step; seen_values++; } int deg; state to_add[6]; current_state.find_to_add(deg, to_add); // cout << "deg " << deg << '\n'; for (int i=0; i<deg; i++) { // cout << "seen "; to_add[i].print(); if (seen_states.find(to_add[i]) == seen_states.end()) { seen_states.insert(to_add[i]); to_add[i].step = current_state.step + 1; my_que.push_back(to_add[i]); // cout << "added "; to_add[i].print(); } } current_state.step = 0; } for (int i=0; i<max_capasity.volume[2]+1; i++) cout << res[i] << ' '; return 0; }
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 | #include <iostream> #include <algorithm> #include <unordered_set> #include <deque> using namespace std; struct state { int volume[3], step; void find_to_add(int& deg, state (&to_add)[6]); bool operator==(const state &other) const { return (volume[0] == other.volume[0] && volume[1] == other.volume[1] && volume[2] == other.volume[2] && step == other.step); } void print() { cout << "state "; for (int i=0; i<3; i++) cout << volume[i] << ' '; cout << ", step " << step << '\n'; } }; int A, B, C, a, b, c; long long res[100007]; state max_capasity; void state::find_to_add(int& deg, state (&to_add)[6]) { deg = 0; for (int i=0; i<3; i++) for (int j=0; j<3; j++) if (i!=j) { // moving from i to j int to_move = min(this->volume[i], max_capasity.volume[j] - this->volume[j]); if (to_move > 0) { state new_state; copy(this->volume, this->volume+3, new_state.volume); new_state.step = 0; new_state.volume[i] -= to_move; new_state.volume[j] += to_move; to_add[deg] = new_state; deg ++; } } return; } struct StateHasher { size_t operator()(const state& my_state) const { size_t ans=0; for (int i=0; i<3; i++) { ans *= 100007; ans += my_state.volume[i]; } return ans; } }; int main() { ios_base::sync_with_stdio(0); cin >> max_capasity.volume[0] >> max_capasity.volume[1] >> max_capasity.volume[2]; cin >> a >> b >> c; state start_capasity {a, b, c, 0}; for (int i=0; i<max_capasity.volume[2]+1; i++) res[i] = -1; int seen_values = 0; int max_value = start_capasity.volume[0] + start_capasity.volume[1] + start_capasity.volume[2]; deque<state> my_que; my_que.push_back(start_capasity); unordered_set<state, StateHasher> seen_states; seen_states.reserve(3*C+7); seen_states.insert(start_capasity); while (not my_que.empty() && (seen_values < max_value + 1)) { state current_state = my_que.front(); // cout << "visiting "; current_state.print(); my_que.pop_front(); for (int i=0; i<3; i++) if (res[current_state.volume[i]] == -1) { res[current_state.volume[i]] = current_state.step; seen_values++; } int deg; state to_add[6]; current_state.find_to_add(deg, to_add); // cout << "deg " << deg << '\n'; for (int i=0; i<deg; i++) { // cout << "seen "; to_add[i].print(); if (seen_states.find(to_add[i]) == seen_states.end()) { seen_states.insert(to_add[i]); to_add[i].step = current_state.step + 1; my_que.push_back(to_add[i]); // cout << "added "; to_add[i].print(); } } current_state.step = 0; } for (int i=0; i<max_capasity.volume[2]+1; i++) cout << res[i] << ' '; return 0; } |