#include <cstdio> #include <vector> #include <cstdint> #include <queue> #include <unordered_map> #include <climits> using Key = std::tuple<int, int, int>; struct KeyHash { size_t operator()(const Key &k) const { static auto hash = std::hash<int>(); size_t seed = hash(std::get<0>(k)); seed = hash(std::get<1>(k)) + 0x9e3779b9 + (seed<<6) + (seed>>2); seed = hash(std::get<2>(k)) + 0x9e3779b9 + (seed<<6) + (seed>>2); return seed; } }; int A, B, C; int a, b, c; std::vector<int> distance; std::unordered_map<Key, int, KeyHash> visited; std::queue<Key> q; // BFS queue void relax(const Key &k, int d) { int ka = std::get<0>(k); int kb = std::get<1>(k); int kc = std::get<2>(k); distance[ka] = std::min(distance[ka], d); distance[kb] = std::min(distance[kb], d); distance[kc] = std::min(distance[kc], d); } void process_node(Key k, int d) { if (visited[k] == 0) { visited[k] = d; relax(k, d); q.emplace(k); } } int main() { scanf("%d %d %d", &A, &B, &C); scanf("%d %d %d", &a, &b, &c); distance.assign(C+1, INT_MAX); distance[a] = 1; distance[b] = 1; distance[c] = 1; q.emplace(a, b, c); visited[std::make_tuple(a, b, c)] = 1; int vcount = 0; while (!q.empty()) { ++vcount; Key k = q.front(); q.pop(); int ka = std::get<0>(k); int kb = std::get<1>(k); int kc = std::get<2>(k); int d = visited[k] + 1; // printf("visit: %d %d %d distance: %d\n", ka, kb, kc, d-2); if (ka > 0) { // pure from A to B int delta = std::min(B - kb, ka); Key n1 = std::make_tuple(ka - delta, kb + delta, kc); process_node(n1, d); // pure from A to C delta = std::min(C - kc, ka); n1 = std::make_tuple(ka - delta, kb, kc + delta); process_node(n1, d); } if (kb > 0) { // pure from B to A int delta = std::min(A - ka, kb); Key n1 = std::make_tuple(ka + delta, kb - delta, kc); process_node(n1, d); // pure from B to C delta = std::min(C - kc, kb); n1 = std::make_tuple(ka, kb - delta, kc + delta); process_node(n1, d); } if (kc > 0) { // pure from C to A int delta = std::min(A - ka, kc); Key n1 = std::make_tuple(ka + delta, kb, kc - delta); process_node(n1, d); // pure from C to B delta = std::min(B - kb, kc); n1 = std::make_tuple(ka, kb + delta, kc - delta); process_node(n1, d); } } for (int i = 0; i <= C; ++i) if (distance[i] < INT_MAX) printf("%d ", distance[i] - 1); else printf("-1 "); printf("\n"); //printf("vcount: %d\n", vcount); 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 | #include <cstdio> #include <vector> #include <cstdint> #include <queue> #include <unordered_map> #include <climits> using Key = std::tuple<int, int, int>; struct KeyHash { size_t operator()(const Key &k) const { static auto hash = std::hash<int>(); size_t seed = hash(std::get<0>(k)); seed = hash(std::get<1>(k)) + 0x9e3779b9 + (seed<<6) + (seed>>2); seed = hash(std::get<2>(k)) + 0x9e3779b9 + (seed<<6) + (seed>>2); return seed; } }; int A, B, C; int a, b, c; std::vector<int> distance; std::unordered_map<Key, int, KeyHash> visited; std::queue<Key> q; // BFS queue void relax(const Key &k, int d) { int ka = std::get<0>(k); int kb = std::get<1>(k); int kc = std::get<2>(k); distance[ka] = std::min(distance[ka], d); distance[kb] = std::min(distance[kb], d); distance[kc] = std::min(distance[kc], d); } void process_node(Key k, int d) { if (visited[k] == 0) { visited[k] = d; relax(k, d); q.emplace(k); } } int main() { scanf("%d %d %d", &A, &B, &C); scanf("%d %d %d", &a, &b, &c); distance.assign(C+1, INT_MAX); distance[a] = 1; distance[b] = 1; distance[c] = 1; q.emplace(a, b, c); visited[std::make_tuple(a, b, c)] = 1; int vcount = 0; while (!q.empty()) { ++vcount; Key k = q.front(); q.pop(); int ka = std::get<0>(k); int kb = std::get<1>(k); int kc = std::get<2>(k); int d = visited[k] + 1; // printf("visit: %d %d %d distance: %d\n", ka, kb, kc, d-2); if (ka > 0) { // pure from A to B int delta = std::min(B - kb, ka); Key n1 = std::make_tuple(ka - delta, kb + delta, kc); process_node(n1, d); // pure from A to C delta = std::min(C - kc, ka); n1 = std::make_tuple(ka - delta, kb, kc + delta); process_node(n1, d); } if (kb > 0) { // pure from B to A int delta = std::min(A - ka, kb); Key n1 = std::make_tuple(ka + delta, kb - delta, kc); process_node(n1, d); // pure from B to C delta = std::min(C - kc, kb); n1 = std::make_tuple(ka, kb - delta, kc + delta); process_node(n1, d); } if (kc > 0) { // pure from C to A int delta = std::min(A - ka, kc); Key n1 = std::make_tuple(ka + delta, kb, kc - delta); process_node(n1, d); // pure from C to B delta = std::min(B - kb, kc); n1 = std::make_tuple(ka, kb + delta, kc - delta); process_node(n1, d); } } for (int i = 0; i <= C; ++i) if (distance[i] < INT_MAX) printf("%d ", distance[i] - 1); else printf("-1 "); printf("\n"); //printf("vcount: %d\n", vcount); return 0; } |