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
125
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <deque>
using namespace std;

struct state {
  int volume[3], step;

  void find_to_add(int& deg, state (&to_add)[6]);

  bool operator==(const state &other) const
  { return (volume[0] == other.volume[0]
            && volume[1] == other.volume[1]
            && volume[2] == other.volume[2]
            && step == other.step);
  }

  void print() {
    cout << "state ";
    for (int i=0; i<3; i++)
      cout << volume[i] << ' ';
    cout << ", step " << step << '\n';
  }
};

int A, B, C, a, b, c;
long long res[100007];

state max_capasity;

void state::find_to_add(int& deg, state (&to_add)[6]) {
  deg = 0;
  for (int i=0; i<3; i++)
    for (int j=0; j<3; j++)
      if (i!=j) {
        // moving from i to j
        int to_move = min(this->volume[i], max_capasity.volume[j] - this->volume[j]);
        if (to_move > 0) {
          state new_state;
          copy(this->volume, this->volume+3, new_state.volume);
          new_state.step = 0;
          new_state.volume[i] -= to_move;
          new_state.volume[j] += to_move;
          to_add[deg] = new_state;
          deg ++;
        }
      }
  return;
}

struct StateHasher
{
  size_t operator()(const state& my_state) const
  {
    size_t ans=0;
    for (int i=0; i<3; i++) {
      ans *= 100007;
      ans += my_state.volume[i];
    }
    return ans;
  }
};

int main()
{
  ios_base::sync_with_stdio(0);

  cin >> max_capasity.volume[0] >> max_capasity.volume[1] >> max_capasity.volume[2];
  cin >> a >> b >> c;
  state start_capasity {a, b, c, 0};

  for (int i=0; i<max_capasity.volume[2]+1; i++)
    res[i] = -1;
  int seen_values = 0;
  int max_value = start_capasity.volume[0] + start_capasity.volume[1] + start_capasity.volume[2];

  deque<state> my_que;
  my_que.push_back(start_capasity);
  
  unordered_set<state, StateHasher> seen_states;
  seen_states.reserve(3*C+7);
  seen_states.insert(start_capasity);

  while (not my_que.empty() && (seen_values < max_value + 1)) {
    state current_state = my_que.front();

//    cout << "visiting "; current_state.print();

    my_que.pop_front();

    for (int i=0; i<3; i++)
      if (res[current_state.volume[i]] == -1) {
        res[current_state.volume[i]] = current_state.step;
        seen_values++;
      }

    int deg;
    state to_add[6];

    current_state.find_to_add(deg, to_add);

//    cout << "deg " << deg << '\n';

    for (int i=0; i<deg; i++) {

//      cout << "seen "; to_add[i].print();

      if (seen_states.find(to_add[i]) == seen_states.end()) {
        seen_states.insert(to_add[i]);
        to_add[i].step = current_state.step + 1;
        my_que.push_back(to_add[i]);

//        cout << "added "; to_add[i].print();
      }
    }
    current_state.step = 0;

  }

  for (int i=0; i<max_capasity.volume[2]+1; i++)
    cout << res[i] << ' ';

  return 0;
}