#include <cstdio> #include <vector> #include <limits> #include <deque> #include <unordered_set> unsigned long long int build(unsigned long long int a, unsigned long long int b, unsigned long long int c) { return a<<40 | b<<20 | c; } unsigned getA(unsigned long long int state) { return state>>40; } unsigned getB(unsigned long long int state) { return (state>>20) & 1048575; } unsigned getC(unsigned long long int state) { return state & 1048575; } int main() { int MA, MB, MC; int CA, CB, CC; scanf("%d %d %d %d %d %d", &MA, &MB, &MC, &CA, &CB, &CC); std::vector<int> result(MC+1, std::numeric_limits<int>::max()); std::deque<std::pair<unsigned long long int, int> > queue; std::unordered_set<unsigned long long int> visited; queue.push_back(std::make_pair(build(CA, CB, CC), 0)); visited.insert(build(CA, CB, CC)); while (!queue.empty()) { int a = getA(queue.begin()->first); int b = getB(queue.begin()->first); int c = getC(queue.begin()->first); int cost = queue.begin()->second; queue.pop_front(); if (a<=MC) result[a] = std::min(result[a], cost); if (b<=MC) result[b] = std::min(result[b], cost); if (c<=MC) result[c] = std::min(result[c], cost); //a to b int x = std::min(MB-b, a); int na = a-x; int nb = b+x; int nc = c; unsigned long long int key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //a to c x = std::min(MC-c, a); na = a-x; nb = b; nc = c+x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //b to a x = std::min(MA-a, b); na = a+x; nb = b-x; nc = c; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //b to c x = std::min(MC-c, b); na = a; nb = b-x; nc = c+x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //c to a x = std::min(MA-a, c); na = a+x; nb = b; nc = c-x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //c to b x = std::min(MB-b, c); na = a; nb = b+x; nc = c-x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } } for (int i=0; i<=MC; ++i) { printf("%d ", ((result[i]<std::numeric_limits<int>::max())?result[i]:-1)); } 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 <limits> #include <deque> #include <unordered_set> unsigned long long int build(unsigned long long int a, unsigned long long int b, unsigned long long int c) { return a<<40 | b<<20 | c; } unsigned getA(unsigned long long int state) { return state>>40; } unsigned getB(unsigned long long int state) { return (state>>20) & 1048575; } unsigned getC(unsigned long long int state) { return state & 1048575; } int main() { int MA, MB, MC; int CA, CB, CC; scanf("%d %d %d %d %d %d", &MA, &MB, &MC, &CA, &CB, &CC); std::vector<int> result(MC+1, std::numeric_limits<int>::max()); std::deque<std::pair<unsigned long long int, int> > queue; std::unordered_set<unsigned long long int> visited; queue.push_back(std::make_pair(build(CA, CB, CC), 0)); visited.insert(build(CA, CB, CC)); while (!queue.empty()) { int a = getA(queue.begin()->first); int b = getB(queue.begin()->first); int c = getC(queue.begin()->first); int cost = queue.begin()->second; queue.pop_front(); if (a<=MC) result[a] = std::min(result[a], cost); if (b<=MC) result[b] = std::min(result[b], cost); if (c<=MC) result[c] = std::min(result[c], cost); //a to b int x = std::min(MB-b, a); int na = a-x; int nb = b+x; int nc = c; unsigned long long int key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //a to c x = std::min(MC-c, a); na = a-x; nb = b; nc = c+x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //b to a x = std::min(MA-a, b); na = a+x; nb = b-x; nc = c; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //b to c x = std::min(MC-c, b); na = a; nb = b-x; nc = c+x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //c to a x = std::min(MA-a, c); na = a+x; nb = b; nc = c-x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } //c to b x = std::min(MB-b, c); na = a; nb = b+x; nc = c-x; key = build(na, nb, nc); if (visited.find(key) == visited.end()) { visited.insert(key); queue.push_back(std::make_pair(key, cost + 1)); } } for (int i=0; i<=MC; ++i) { printf("%d ", ((result[i]<std::numeric_limits<int>::max())?result[i]:-1)); } return 0; } |