#include <iostream> #include <set> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <list> using namespace std; #undef _HOME_ #ifdef _HOME_ #define DEBUG2(x) x #define DEBUG(x) x #else #define DEBUG(x) #endif #ifndef DEBUG2 #define DEBUG2(x) #endif #define REP(x,n) for(int x=0;x<(n);++x) #define FOREACH(x,n) for(__typeof(n.begin()) x = (n).begin(); x != (n).end(); ++x) #define RESULT(x) {cout<<(x);return 0;} const int MAX_N = 100001; int solutions[MAX_N]; int A,B,C,a,b,c; struct State { int a,b,c; int time; bool operator<(const State& other) const { return time<other.time; } }; ostream& operator<<(ostream& os, const State& s) { return os<<"{"<<s.a<<","<<s.b<<","<<s.c<<"} at time "<<s.time; } struct Triple { int a,b,c; bool operator<(const Triple& o) const { return a != o.a ? a<o.a : b != o.b ? b < o.b : c < o.c; } }; ostream& operator<<(ostream& os, const Triple& s) { return os<<"{"<<s.a<<","<<s.b<<","<<s.c<<"}"; } std::list<State> queue; set<Triple> processed; void inline addQueue(int a, int b, int c, int time) { Triple newTriple{a,b,c}; if (processed.find(newTriple)!=processed.end()) { DEBUG(cerr<<"triple "<<newTriple<<" already exists"<<endl;) return; } DEBUG(cerr<<"adding triple "<<newTriple<<" at time "<<time<<endl;) queue.push_back(std::move(State{a,b,c,time})); processed.insert(std::move(newTriple)); #define MAYBEADD(x) \ if (solutions[x] == -1) {\ solutions[x] = time; \ DEBUG(cerr<<"solution for "<<x<<" is "<<time<<" at "<<#x<<endl;) \ } MAYBEADD(a); MAYBEADD(b); MAYBEADD(c); } void inline processTriple(const int& a, const int& b, const int& c, const int& cindex, const int& time) { DEBUG2(cerr<<"processTriple "<<a<<","<<b<<","<<c<<" - "<<cindex<<" "<<time<<endl;) if(cindex == 1) addQueue(c,a,b,time); else if (cindex == 2) addQueue(a,c,b,time); else addQueue(a,b,c,time); } void inline tryMix(const int& a, const int& b, const int& A, const int& B, const int& c, const int& cindex, const int& time) { if (a!=A) { int change = min(A-a,b); DEBUG(cerr<<"after change1 "<<cindex<<" - "<<change<<" - "<<a+change<<"/"<<A<<", "<<b-change<<"/"<<B<<", unchanged "<<c<<endl;) processTriple(a+change, b-change, c, cindex, time+1); } if (b!=B) { int change = min(B-b,a); DEBUG(cerr<<"after change2 "<<cindex<<" - "<<change<<" - "<<a-change<<"/"<<A<<", "<<b+change<<"/"<<B<<", unchanged "<<c<<endl;) processTriple(a-change, b+change, c, cindex, time+1); } } int main() { ios_base::sync_with_stdio(0); cin>>A>>B>>C>>a>>b>>c; REP(x,C+1) solutions[x] = -1; addQueue(a,b,c,0); while(!queue.empty()) { State& s = queue.front(); DEBUG(cerr<<"processing "<<s<<"; queue size is "<<queue.size()<<endl;) DEBUG(cerr<<"check a,b"<<endl;) tryMix(s.a,s.b,A,B,s.c,3,s.time); DEBUG(cerr<<"check a,c"<<endl;) tryMix(s.a,s.c,A,C,s.b,2,s.time); DEBUG(cerr<<"check b,c"<<endl;) tryMix(s.b,s.c,B,C,s.a,1,s.time); queue.pop_front(); } REP(x,C+1) cout << solutions[x]<<" "; 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 | #include <iostream> #include <set> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <list> using namespace std; #undef _HOME_ #ifdef _HOME_ #define DEBUG2(x) x #define DEBUG(x) x #else #define DEBUG(x) #endif #ifndef DEBUG2 #define DEBUG2(x) #endif #define REP(x,n) for(int x=0;x<(n);++x) #define FOREACH(x,n) for(__typeof(n.begin()) x = (n).begin(); x != (n).end(); ++x) #define RESULT(x) {cout<<(x);return 0;} const int MAX_N = 100001; int solutions[MAX_N]; int A,B,C,a,b,c; struct State { int a,b,c; int time; bool operator<(const State& other) const { return time<other.time; } }; ostream& operator<<(ostream& os, const State& s) { return os<<"{"<<s.a<<","<<s.b<<","<<s.c<<"} at time "<<s.time; } struct Triple { int a,b,c; bool operator<(const Triple& o) const { return a != o.a ? a<o.a : b != o.b ? b < o.b : c < o.c; } }; ostream& operator<<(ostream& os, const Triple& s) { return os<<"{"<<s.a<<","<<s.b<<","<<s.c<<"}"; } std::list<State> queue; set<Triple> processed; void inline addQueue(int a, int b, int c, int time) { Triple newTriple{a,b,c}; if (processed.find(newTriple)!=processed.end()) { DEBUG(cerr<<"triple "<<newTriple<<" already exists"<<endl;) return; } DEBUG(cerr<<"adding triple "<<newTriple<<" at time "<<time<<endl;) queue.push_back(std::move(State{a,b,c,time})); processed.insert(std::move(newTriple)); #define MAYBEADD(x) \ if (solutions[x] == -1) {\ solutions[x] = time; \ DEBUG(cerr<<"solution for "<<x<<" is "<<time<<" at "<<#x<<endl;) \ } MAYBEADD(a); MAYBEADD(b); MAYBEADD(c); } void inline processTriple(const int& a, const int& b, const int& c, const int& cindex, const int& time) { DEBUG2(cerr<<"processTriple "<<a<<","<<b<<","<<c<<" - "<<cindex<<" "<<time<<endl;) if(cindex == 1) addQueue(c,a,b,time); else if (cindex == 2) addQueue(a,c,b,time); else addQueue(a,b,c,time); } void inline tryMix(const int& a, const int& b, const int& A, const int& B, const int& c, const int& cindex, const int& time) { if (a!=A) { int change = min(A-a,b); DEBUG(cerr<<"after change1 "<<cindex<<" - "<<change<<" - "<<a+change<<"/"<<A<<", "<<b-change<<"/"<<B<<", unchanged "<<c<<endl;) processTriple(a+change, b-change, c, cindex, time+1); } if (b!=B) { int change = min(B-b,a); DEBUG(cerr<<"after change2 "<<cindex<<" - "<<change<<" - "<<a-change<<"/"<<A<<", "<<b+change<<"/"<<B<<", unchanged "<<c<<endl;) processTriple(a-change, b+change, c, cindex, time+1); } } int main() { ios_base::sync_with_stdio(0); cin>>A>>B>>C>>a>>b>>c; REP(x,C+1) solutions[x] = -1; addQueue(a,b,c,0); while(!queue.empty()) { State& s = queue.front(); DEBUG(cerr<<"processing "<<s<<"; queue size is "<<queue.size()<<endl;) DEBUG(cerr<<"check a,b"<<endl;) tryMix(s.a,s.b,A,B,s.c,3,s.time); DEBUG(cerr<<"check a,c"<<endl;) tryMix(s.a,s.c,A,C,s.b,2,s.time); DEBUG(cerr<<"check b,c"<<endl;) tryMix(s.b,s.c,B,C,s.a,1,s.time); queue.pop_front(); } REP(x,C+1) cout << solutions[x]<<" "; return 0; } |