#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; } |
English