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