#include <iostream> #include <unordered_set> #include <queue> #include <cassert> #include <algorithm> #include <vector> #include <set> #include <map> #include <numeric> #include <assert.h> #include <tuple> using state = std::tuple<int, int, int>; #define TOLL(a, b, c) (((static_cast<size_t>(a) << 18ll) << 18ll) + (static_cast<size_t>(b) << 18ll) + static_cast<size_t>(c)) struct state_hash { size_t operator()(state const& tt) const { return TOLL(std::get<2>(tt), std::get<1>(tt), std::get<0>(tt)); } }; using namespace std; using ull = unsigned long long; using ll = long long; #ifdef GGDEBUG #define dbg printf #else #define dbg //dbg #endif state capacity; template<int from, int to> state transfer(state now) { int move = min(get<from>(now), get<to>(capacity) - get<to>(now)); get<from>(now) -= move; get<to>(now) += move; return now; } std::ostream& operator<<(std::ostream& os, const state& s) { os << get<0>(s) << " " << get<1>(s) << " " << get<2>(s); return os; } static_assert(sizeof(size_t) == 8, "size_t is not 64 bit"); int main() { int a, b, c; scanf("%d%d%d", &a, &b, &c); capacity = make_tuple(a, b, c); int x1, x2, x3; scanf("%d%d%d", &x1, &x2, &x3); vector<int> results; results.resize(c+1, -1); int to_calculate = c+1; unordered_set<state, state_hash> visited; queue<pair<state, int>> q; q.push(make_pair(make_tuple(x1, x2, x3), 0)); while (!q.empty()) { auto q_now = q.front(); state cur = q_now.first; int cnt = q_now.second; q.pop(); // cout << "State now: " << cur << endl; if (visited.count(cur)) { continue; } visited.insert(cur); int a = get<0>(cur); int b = get<1>(cur); int c = get<2>(cur); if (results[a] == -1) { results[a] = cnt; to_calculate--; } if (results[b] == -1) { results[b] = cnt; to_calculate--; } if (results[c] == -1) { results[c] = cnt; to_calculate--; } if (to_calculate == 0) { break; } q.push(make_pair(transfer<0, 1>(cur), cnt+1)); q.push(make_pair(transfer<0, 2>(cur), cnt+1)); q.push(make_pair(transfer<1, 0>(cur), cnt+1)); q.push(make_pair(transfer<1, 2>(cur), cnt+1)); q.push(make_pair(transfer<2, 0>(cur), cnt+1)); q.push(make_pair(transfer<2, 1>(cur), cnt+1)); } for (int i = 0; i <= c; i++) { printf("%d ", results[i]); } printf("\n"); // cout << sizeof(size_t) << endl; 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 | #include <iostream> #include <unordered_set> #include <queue> #include <cassert> #include <algorithm> #include <vector> #include <set> #include <map> #include <numeric> #include <assert.h> #include <tuple> using state = std::tuple<int, int, int>; #define TOLL(a, b, c) (((static_cast<size_t>(a) << 18ll) << 18ll) + (static_cast<size_t>(b) << 18ll) + static_cast<size_t>(c)) struct state_hash { size_t operator()(state const& tt) const { return TOLL(std::get<2>(tt), std::get<1>(tt), std::get<0>(tt)); } }; using namespace std; using ull = unsigned long long; using ll = long long; #ifdef GGDEBUG #define dbg printf #else #define dbg //dbg #endif state capacity; template<int from, int to> state transfer(state now) { int move = min(get<from>(now), get<to>(capacity) - get<to>(now)); get<from>(now) -= move; get<to>(now) += move; return now; } std::ostream& operator<<(std::ostream& os, const state& s) { os << get<0>(s) << " " << get<1>(s) << " " << get<2>(s); return os; } static_assert(sizeof(size_t) == 8, "size_t is not 64 bit"); int main() { int a, b, c; scanf("%d%d%d", &a, &b, &c); capacity = make_tuple(a, b, c); int x1, x2, x3; scanf("%d%d%d", &x1, &x2, &x3); vector<int> results; results.resize(c+1, -1); int to_calculate = c+1; unordered_set<state, state_hash> visited; queue<pair<state, int>> q; q.push(make_pair(make_tuple(x1, x2, x3), 0)); while (!q.empty()) { auto q_now = q.front(); state cur = q_now.first; int cnt = q_now.second; q.pop(); // cout << "State now: " << cur << endl; if (visited.count(cur)) { continue; } visited.insert(cur); int a = get<0>(cur); int b = get<1>(cur); int c = get<2>(cur); if (results[a] == -1) { results[a] = cnt; to_calculate--; } if (results[b] == -1) { results[b] = cnt; to_calculate--; } if (results[c] == -1) { results[c] = cnt; to_calculate--; } if (to_calculate == 0) { break; } q.push(make_pair(transfer<0, 1>(cur), cnt+1)); q.push(make_pair(transfer<0, 2>(cur), cnt+1)); q.push(make_pair(transfer<1, 0>(cur), cnt+1)); q.push(make_pair(transfer<1, 2>(cur), cnt+1)); q.push(make_pair(transfer<2, 0>(cur), cnt+1)); q.push(make_pair(transfer<2, 1>(cur), cnt+1)); } for (int i = 0; i <= c; i++) { printf("%d ", results[i]); } printf("\n"); // cout << sizeof(size_t) << endl; return 0; } |