#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <unordered_map> #include <queue> using namespace std; const int P1 = 321656459; const int P2 = 78155521; const int P3 = 136551731; struct MyTriple { int val[3]; MyTriple(int x, int y, int z) { this->val[0] = x; this->val[1] = y; this->val[2] = z; } bool operator==(const MyTriple& oth) const { return val[0] == oth.val[0] && val[1] == oth.val[1] && val[2] == oth.val[2]; } }; struct TripleHash { size_t operator()(const MyTriple& mt) const { return mt.val[0] * P1 + mt.val[1] * P2 + mt.val[2] * P3; } }; int ans[100005]; int max_cap[3]; int cap[3]; unordered_map<MyTriple, int, TripleHash> dist; queue<MyTriple> q; MyTriple move(MyTriple setting, int from, int to) { MyTriple result = setting; int remaining = max_cap[to] - result.val[to]; int left_in_1 = 0; int poured_into_2 = result.val[from]; if (poured_into_2 > remaining) { left_in_1 = poured_into_2 - remaining; poured_into_2 = remaining; } result.val[from] = left_in_1; result.val[to] += poured_into_2; return result; } inline bool contains(MyTriple val) { auto search = dist.find(val); return search != dist.end(); } void bfs() { MyTriple setting = MyTriple(cap[0], cap[1], cap[2]); dist[setting] = 0; q.push(setting); while (!q.empty()) { setting = q.front(); q.pop(); for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) { if (i == j) continue; MyTriple new_setting = move(setting, i, j); if (contains(new_setting)) continue; int cur_dist = dist[new_setting] = dist[setting] + 1; for (int k = 0; k < 3; ++k) if (ans[new_setting.val[k]] == -1) ans[new_setting.val[k]] = cur_dist; q.push(new_setting); } } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> max_cap[0]; cin >> max_cap[1]; cin >> max_cap[2]; cin >> cap[0]; cin >> cap[1]; cin >> cap[2]; for (int i = 0; i <= max_cap[2]; ++i) ans[i] = -1; ans[cap[0]] = ans[cap[1]] = ans[cap[2]] = 0; bfs(); for (int i = 0; i <= max_cap[2]; ++i) cout << ans[i] << " "; cout << "\n"; 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 | #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <unordered_map> #include <queue> using namespace std; const int P1 = 321656459; const int P2 = 78155521; const int P3 = 136551731; struct MyTriple { int val[3]; MyTriple(int x, int y, int z) { this->val[0] = x; this->val[1] = y; this->val[2] = z; } bool operator==(const MyTriple& oth) const { return val[0] == oth.val[0] && val[1] == oth.val[1] && val[2] == oth.val[2]; } }; struct TripleHash { size_t operator()(const MyTriple& mt) const { return mt.val[0] * P1 + mt.val[1] * P2 + mt.val[2] * P3; } }; int ans[100005]; int max_cap[3]; int cap[3]; unordered_map<MyTriple, int, TripleHash> dist; queue<MyTriple> q; MyTriple move(MyTriple setting, int from, int to) { MyTriple result = setting; int remaining = max_cap[to] - result.val[to]; int left_in_1 = 0; int poured_into_2 = result.val[from]; if (poured_into_2 > remaining) { left_in_1 = poured_into_2 - remaining; poured_into_2 = remaining; } result.val[from] = left_in_1; result.val[to] += poured_into_2; return result; } inline bool contains(MyTriple val) { auto search = dist.find(val); return search != dist.end(); } void bfs() { MyTriple setting = MyTriple(cap[0], cap[1], cap[2]); dist[setting] = 0; q.push(setting); while (!q.empty()) { setting = q.front(); q.pop(); for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) { if (i == j) continue; MyTriple new_setting = move(setting, i, j); if (contains(new_setting)) continue; int cur_dist = dist[new_setting] = dist[setting] + 1; for (int k = 0; k < 3; ++k) if (ans[new_setting.val[k]] == -1) ans[new_setting.val[k]] = cur_dist; q.push(new_setting); } } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> max_cap[0]; cin >> max_cap[1]; cin >> max_cap[2]; cin >> cap[0]; cin >> cap[1]; cin >> cap[2]; for (int i = 0; i <= max_cap[2]; ++i) ans[i] = -1; ans[cap[0]] = ans[cap[1]] = ans[cap[2]] = 0; bfs(); for (int i = 0; i <= max_cap[2]; ++i) cout << ans[i] << " "; cout << "\n"; return 0; } |