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
#include <cstdio>
#include <cstring>
#include <queue>
#include <unordered_set>
#include <utility>

struct State {
  int a, b, c;

  bool operator==(const State &other) const { return (a == other.a && b == other.b && c == other.c); }
} maxes;

struct StateHasher {
  std::size_t operator()(const State &t) const {
    size_t res = 17;
    res = res * 31 + t.a;
    res = res * 31 + t.b;
    res = res * 31 + t.c;
    return res;
  }
};

inline int _min(int a, int b) { return (a < b) ? a : b; }

inline int _max(int a, int b) { return (a > b) ? a : b; }

const int NN = 100100;

int found = 0;
int all;
int dists[NN];
std::unordered_set<State, StateHasher> hash;
std::queue<std::pair<State, int>> queue;

inline bool update(int v, int dist) {
  if (dists[v] == 0) {
    dists[v] = dist;
    return ++found == all;
  }
  return false;
}

inline void try_put(int tr, State s1, int dist) {
  if (tr && hash.find(s1) == hash.end()) {
    hash.insert(s1);
    queue.push({s1, dist});
  }
}

int main() {
  memset(dists, 0, NN);
  State start;
  scanf("%d%d%d", &maxes.a, &maxes.b, &maxes.c);
  scanf("%d%d%d", &start.a, &start.b, &start.c);

  all = maxes.c + 1;

  hash.insert(start);
  queue.push({start, 0});
  int tr;

  while (!queue.empty()) {
    auto elem = queue.front();
    queue.pop();
    State s = elem.first;
    State s1;
    int dist = elem.second + 1;

    if (update(s.a, dist)) break;
    if (update(s.b, dist)) break;
    if (update(s.c, dist)) break;

    tr = _min(s.a, maxes.b - s.b); try_put(tr, {s.a - tr, s.b + tr, s.c}, dist);
    tr = _min(s.a, maxes.c - s.c); try_put(tr, {s.a - tr, s.b, s.c + tr}, dist);

    tr = _min(s.b, maxes.a - s.a); try_put(tr, {s.a + tr, s.b - tr, s.c}, dist);
    tr = _min(s.b, maxes.c - s.c); try_put(tr, {s.a, s.b - tr, s.c + tr}, dist);

    tr = _min(s.c, maxes.a - s.a); try_put(tr, {s.a + tr, s.b, s.c - tr}, dist);
    tr = _min(s.c, maxes.b - s.b); try_put(tr, {s.a, s.b + tr, s.c - tr}, dist);
  }

  for (int i = 0; i < all; ++i) {
    printf("%d ", dists[i] - 1);
  }
  printf("\n");
  return 0;
}