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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <iostream>
#include <vector>
#include <climits>
#include <unordered_map>
#include <queue>
#include <algorithm>
using namespace std;

int A, B, C;

typedef tuple<int, int, int> vertex;
constexpr int P = 1696969;

namespace std {
    template<>
    struct hash<vertex> {
        size_t operator() (const vertex& x) const& {
            auto [a, b, c] = x;
            return ((a * P) + b) * P + c;
        }
    };
}


int main()
{
    cin.tie(0);
    ios_base::sync_with_stdio(0);

    int c, b, a, w;
    cin >> C >> B >> A;
    cin >> c >> b >> a;
    w = a + b + c;

    vector <int> res(A + 1, INT_MAX);
    res[a] = 0;
    res[b] = 0;
    res[c] = 0;
    
    unordered_map <vertex, vector<vertex>> G;

    vector <vertex> gen;

    for (int i = 0; i <= min(w, A); i++)
        for (int j = 0; j <= min(w-i, B); j++)
            if (w-i-j<=C)
                gen.push_back({i, j, w-i-j});
          

    //wg pierwszego
    sort(gen.begin(), gen.end());
    vector <int> ends;
    ends.push_back(0);
    int temp = get<0>(gen[0]);
    for (int i = 0; i < gen.size(); i++) {
        if (get<0>(gen[i]) != temp) {
            temp = get<0>(gen[i]);
            ends.push_back(i);
        }
    }
    ends.push_back(gen.size());
    temp = 1; 

    while (temp < ends.size()) {
        for (int i = ends[temp-1]; i < ends[temp]; i++)
            for (int j = ends[temp-1]; j < ends[temp]; j++)
                if (i != j && gen[i] != gen[j])
                    if ((get<2>(gen[i]) < get<2>(gen[j]) && (get<1>(gen[j]) == 0) || get<2>(gen[j]) == C)
                        ||(get<1>(gen[i]) < get<1>(gen[j]) && (get<2>(gen[j]) == 0) || get<1>(gen[j]) == B)
                        )
                        G[gen[i]].push_back(gen[j]);
        temp++;
    }

    //wg drugiego
    sort(gen.begin(), gen.end(), [&](vertex a, vertex b) {return get<1>(a) < get<1>(b); });
    ends.clear();
    ends.push_back(0);
    temp = get<1>(gen[0]);
    for (int i = 0; i < gen.size(); i++) {
        if (get<1>(gen[i]) != temp) {
            temp = get<1>(gen[i]);
            ends.push_back(i);
        }
    }
    ends.push_back(gen.size());
    temp = 1;

    while (temp < ends.size()) {
        for (int i = ends[temp - 1]; i < ends[temp]; i++)
            for (int j = ends[temp - 1]; j < ends[temp]; j++)
                if (i != j && gen[i] != gen[j])
                    if ((get<2>(gen[i]) < get<2>(gen[j]) && (get<0>(gen[j]) == 0) || get<2>(gen[j]) == C)
                        ||(get<0>(gen[i]) < get<0>(gen[j]) && (get<2>(gen[j]) == 0) || get<0>(gen[j]) == A)
                        )
                        G[gen[i]].push_back(gen[j]);
        temp++;
    }

    //wg trzeciego
    sort(gen.begin(), gen.end(), [&](vertex a, vertex b) {return get<2>(a) < get<2>(b); });
    ends.clear();
    ends.push_back(0);
    temp = get<2>(gen[0]);
    for (int i = 0; i < gen.size(); i++) {
        if (get<2>(gen[i]) != temp) {
            temp = get<2>(gen[i]);
            ends.push_back(i);
        }
    }
    ends.push_back(gen.size());
    temp = 1;

    while (temp < ends.size()) {
        for (int i = ends[temp - 1]; i < ends[temp]; i++)
            for (int j = ends[temp - 1]; j < ends[temp]; j++)
                if (i != j && gen[i] != gen[j])
                    if ((get<1>(gen[i]) < get<1>(gen[j]) && (get<0>(gen[j]) == 0) || get<1>(gen[j]) == B)
                        || (get<0>(gen[i]) < get<0>(gen[j]) && (get<1>(gen[j]) == 0) || get<0>(gen[j]) == A)
                        )
                        G[gen[i]].push_back(gen[j]);    
        temp++;
    }


    auto bfs = [&](vertex v) {
        unordered_map <vertex, int> dist;
        dist[v] = 0;
        queue<vertex> Q;
        Q.push(v);

        while (!Q.empty()) {
            vertex u = Q.front();
            Q.pop();

            for (auto [w1, w2, w3] : G[u]) {
                if (!dist.count({ w1, w2, w3 })) {
                    dist[{w1, w2, w3}] = dist[u] + 1;
                    res[w1] = min(res[w1], dist[{w1, w2, w3}]);
                    res[w2] = min(res[w2], dist[{w1, w2, w3}]);
                    res[w3] = min(res[w3], dist[{w1, w2, w3}]);
                    Q.push({ w1, w2, w3 });
                }
            }
        }
    };

    bfs({ a, b, c });

    for (int i = 0; i <= A; i++) {
        if (res[i] == INT_MAX)
            cout << -1 << " ";
        else
            cout << res[i] << " ";
    }
    cout << "\n";
}