#include <cstdio> #include <cstring> #include <cmath> #include <cassert> #include <iostream> #include <algorithm> #include <iterator> #include <string> #include <vector> #include <queue> #include <bitset> #include <utility> #include <stack> #include <unordered_set> #include <tuple> #include <functional> namespace hash_tuple { template <typename TT> struct hash { size_t operator()(TT const &tt) const { return std::hash<TT>()(tt); } }; // from boost (functional/hash): // see http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html template template <class T> inline void hash_combine(std::size_t &seed, T const &v) { seed ^= hash_tuple::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } // Recursive template code derived from Matthieu M. template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { void operator()(size_t &seed, Tuple const &tuple) const { HashValueImpl<Tuple, Index - 1>{}(seed, tuple); hash_combine(seed, std::get<Index>(tuple)); } }; template <class Tuple> struct HashValueImpl<Tuple, 0> { void operator()(size_t &seed, Tuple const &tuple) const { hash_combine(seed, std::get<0>(tuple)); } }; template <typename... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const &tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...>>{}(seed, tt); return seed; } }; // auxiliary generic functions to create a hash value using a seed template <typename T> inline void hash_val(std::size_t &seed, const T &val) { hash_combine(seed, val); } template <typename T, typename... Types> inline void hash_val(std::size_t &seed, const T &val, const Types &... args) { hash_combine(seed, val); hash_val(seed, args...); } template <typename... Types> inline std::size_t hash_val(const Types &... args) { std::size_t seed = 0; hash_val(seed, args...); return seed; } struct pair_hash { template <class T1, class T2> std::size_t operator()(const std::pair<T1, T2> &p) const { return hash_val(p.first, p.second); } }; struct tuple_hash { template <class T1, class T2, class T3> std::size_t operator()(const std::tuple<T1, T2, T3> &t) const { return hash_val(std::get<0>(t), std::get<1>(t), std::get<2>(t)); } }; } // namespace hash_tuple using namespace std; typedef long long LL; typedef pair<int,int> PII; typedef vector<int> VI; #define MP make_pair #define FOR(v,p,k) for(int v=(p);v<=(k);++v) #define FORD(v,p,k) for(int v=(p);v>=(k);--v) #define REP(i,n) for(int i=0;i<(n);++i) #define VAR(v,i) __typeof(i) v=(i) #define FOREACH(i,c) for(VAR(i,(c).begin());i!=(c).end();++i) #define PB push_back #define ST first #define ND second #define SIZE(x) (int)x.size() #define ALL(c) c.begin(),c.end() #define ODD(x) ((x)%2) #define EVEN(x) (!(ODD(x))) typedef tuple<int, int, int> TIII; int main() { VI R(3), r(3), candv(3); scanf("%d %d %d\n", &R[0], &R[1], &R[2]); scanf("%d %d %d\n", &r[0], &r[1], &r[2]); int C = R[2]; VI res(C + 1, -1); unordered_set<TIII, hash_tuple::tuple_hash> visited; vector<TIII> curr, next; curr.PB(make_tuple(r[0], r[1], r[2])); int iter = -1; while (!curr.empty()) { ++iter; FOREACH(i, curr) { tie(r[0], r[1], r[2]) = *i; FOREACH(it, r) { int x = *it; if (res[x] == -1) { res[x] = iter; } } visited.insert(*i); REP(i, 3) { REP(j, 3) { if ((i == j) || (r[i] == R[i]) || r[j] == 0) continue; candv[i] = min(R[i], r[i] + r[j]); candv[j] = max(0, r[j] - (R[i] - r[i])); candv[3 - i - j] = r[3 - i - j]; TIII cand = make_tuple(candv[0], candv[1], candv[2]); if (visited.count(cand) == 0) { next.PB(cand); } } } } curr.clear(); swap(curr, next); } REP(i, C + 1) { printf("%d%s", res[i], (i <= C) ? " " : ""); } 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 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 | #include <cstdio> #include <cstring> #include <cmath> #include <cassert> #include <iostream> #include <algorithm> #include <iterator> #include <string> #include <vector> #include <queue> #include <bitset> #include <utility> #include <stack> #include <unordered_set> #include <tuple> #include <functional> namespace hash_tuple { template <typename TT> struct hash { size_t operator()(TT const &tt) const { return std::hash<TT>()(tt); } }; // from boost (functional/hash): // see http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html template template <class T> inline void hash_combine(std::size_t &seed, T const &v) { seed ^= hash_tuple::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } // Recursive template code derived from Matthieu M. template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { void operator()(size_t &seed, Tuple const &tuple) const { HashValueImpl<Tuple, Index - 1>{}(seed, tuple); hash_combine(seed, std::get<Index>(tuple)); } }; template <class Tuple> struct HashValueImpl<Tuple, 0> { void operator()(size_t &seed, Tuple const &tuple) const { hash_combine(seed, std::get<0>(tuple)); } }; template <typename... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const &tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...>>{}(seed, tt); return seed; } }; // auxiliary generic functions to create a hash value using a seed template <typename T> inline void hash_val(std::size_t &seed, const T &val) { hash_combine(seed, val); } template <typename T, typename... Types> inline void hash_val(std::size_t &seed, const T &val, const Types &... args) { hash_combine(seed, val); hash_val(seed, args...); } template <typename... Types> inline std::size_t hash_val(const Types &... args) { std::size_t seed = 0; hash_val(seed, args...); return seed; } struct pair_hash { template <class T1, class T2> std::size_t operator()(const std::pair<T1, T2> &p) const { return hash_val(p.first, p.second); } }; struct tuple_hash { template <class T1, class T2, class T3> std::size_t operator()(const std::tuple<T1, T2, T3> &t) const { return hash_val(std::get<0>(t), std::get<1>(t), std::get<2>(t)); } }; } // namespace hash_tuple using namespace std; typedef long long LL; typedef pair<int,int> PII; typedef vector<int> VI; #define MP make_pair #define FOR(v,p,k) for(int v=(p);v<=(k);++v) #define FORD(v,p,k) for(int v=(p);v>=(k);--v) #define REP(i,n) for(int i=0;i<(n);++i) #define VAR(v,i) __typeof(i) v=(i) #define FOREACH(i,c) for(VAR(i,(c).begin());i!=(c).end();++i) #define PB push_back #define ST first #define ND second #define SIZE(x) (int)x.size() #define ALL(c) c.begin(),c.end() #define ODD(x) ((x)%2) #define EVEN(x) (!(ODD(x))) typedef tuple<int, int, int> TIII; int main() { VI R(3), r(3), candv(3); scanf("%d %d %d\n", &R[0], &R[1], &R[2]); scanf("%d %d %d\n", &r[0], &r[1], &r[2]); int C = R[2]; VI res(C + 1, -1); unordered_set<TIII, hash_tuple::tuple_hash> visited; vector<TIII> curr, next; curr.PB(make_tuple(r[0], r[1], r[2])); int iter = -1; while (!curr.empty()) { ++iter; FOREACH(i, curr) { tie(r[0], r[1], r[2]) = *i; FOREACH(it, r) { int x = *it; if (res[x] == -1) { res[x] = iter; } } visited.insert(*i); REP(i, 3) { REP(j, 3) { if ((i == j) || (r[i] == R[i]) || r[j] == 0) continue; candv[i] = min(R[i], r[i] + r[j]); candv[j] = max(0, r[j] - (R[i] - r[i])); candv[3 - i - j] = r[3 - i - j]; TIII cand = make_tuple(candv[0], candv[1], candv[2]); if (visited.count(cand) == 0) { next.PB(cand); } } } } curr.clear(); swap(curr, next); } REP(i, C + 1) { printf("%d%s", res[i], (i <= C) ? " " : ""); } return 0; } |