#include <stdio.h> #include <string.h> #include <unordered_map> #include <unordered_set> #include <set> #include <queue> #define MOD_VAL 1000000007 #define MAX_SIZE 100001 //int A,B,C; int SIZES[3]; int steps[MAX_SIZE]; class State{ public: int val[3]; std::size_t hash; State(){ val[0] = 0; val[1] = 0; val[2] = 0; calcHash(); } State(int a, int b, int c){ val[0] = a; val[1] = b; val[2] = c; calcHash(); // this->hash = (((a & 0xFFFF) << 16) | (b & 0xFFFF)) ^ c; } bool operator<(const State & c) const { if (this->val[0] > c.val[0]) return 0; if (this->val[0] < c.val[0]) return 1; if (this->val[1] > c.val[1]) return 0; if (this->val[1] < c.val[1]) return 1; return this->val[2] < c.val[2]; } void calcHash(){ this->hash = (((val[0] & 0xFFFF) << 16) | (val[1] & 0xFFFF)) ^ val[2]; } bool operator==(const State &s) const{ return s.val[0] == this->val[0] && s.val[1] == this->val[1] && s.val[2] == this->val[2]; } }; //typedef std::tuple<int, int, int> Stan; typedef std::pair<State, int> Krok; struct HashStruct{ std::size_t operator()(const State &s) const { return s.hash; } }; int min(int a , int b){ return a < b ? a : b; } void getStan(const State & source, State & dest, int sIdx, int dIdx, int restIdx){ int total = source.val[sIdx] + source.val[dIdx]; dest.val[dIdx] = min(total, SIZES[dIdx]); dest.val[sIdx] = total - dest.val[dIdx]; dest.val[restIdx] = source.val[restIdx]; dest.calcHash(); } int found = 0; void update(int val, int k){ if (steps[val] == -1){ steps[val] = k; ++found; } } int main(){ int a, b, c; memset(steps, -1, MAX_SIZE * sizeof(int)); scanf("%d %d %d", &SIZES[0], &SIZES[1], &SIZES[2]); scanf("%d %d %d", &a, &b, &c); // std::unordered_set<State, HashStruct> visited; std::set<State> visited; std::queue<Krok> queue; State start(a,b,c); queue.push(Krok(start,0)); visited.insert(start); State stany[6]; while (!queue.empty() && found < SIZES[2] + 1){ Krok k = queue.front(); queue.pop(); update(k.first.val[0], k.second); update(k.first.val[1], k.second); update(k.first.val[2], k.second); // printf("STAN %d %d %d\n",k.first.val[0],k.first.val[1],k.first.val[2]); getStan(k.first, stany[0], 0, 1, 2); getStan(k.first, stany[1], 0, 2, 1); getStan(k.first, stany[2], 1, 0, 2); getStan(k.first, stany[3], 1, 2, 0); getStan(k.first, stany[4], 2, 0, 1); getStan(k.first, stany[5], 2, 1, 0); for(int i = 0; i < 6; ++i){ // printf("=== %d %d %d\n",stany[i].val[0],stany[i].val[1],stany[i].val[2]); if (visited.find(stany[i]) == visited.end()){ // printf(">>> %d %d %d\n",stany[i].val[0],stany[i].val[1],stany[i].val[2]); visited.insert(stany[i]); queue.push(Krok(stany[i],k.second + 1)); } } } for(int i = 0; i < SIZES[2] + 1; ++i) printf("%d ", steps[i]); printf("\n"); 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 | #include <stdio.h> #include <string.h> #include <unordered_map> #include <unordered_set> #include <set> #include <queue> #define MOD_VAL 1000000007 #define MAX_SIZE 100001 //int A,B,C; int SIZES[3]; int steps[MAX_SIZE]; class State{ public: int val[3]; std::size_t hash; State(){ val[0] = 0; val[1] = 0; val[2] = 0; calcHash(); } State(int a, int b, int c){ val[0] = a; val[1] = b; val[2] = c; calcHash(); // this->hash = (((a & 0xFFFF) << 16) | (b & 0xFFFF)) ^ c; } bool operator<(const State & c) const { if (this->val[0] > c.val[0]) return 0; if (this->val[0] < c.val[0]) return 1; if (this->val[1] > c.val[1]) return 0; if (this->val[1] < c.val[1]) return 1; return this->val[2] < c.val[2]; } void calcHash(){ this->hash = (((val[0] & 0xFFFF) << 16) | (val[1] & 0xFFFF)) ^ val[2]; } bool operator==(const State &s) const{ return s.val[0] == this->val[0] && s.val[1] == this->val[1] && s.val[2] == this->val[2]; } }; //typedef std::tuple<int, int, int> Stan; typedef std::pair<State, int> Krok; struct HashStruct{ std::size_t operator()(const State &s) const { return s.hash; } }; int min(int a , int b){ return a < b ? a : b; } void getStan(const State & source, State & dest, int sIdx, int dIdx, int restIdx){ int total = source.val[sIdx] + source.val[dIdx]; dest.val[dIdx] = min(total, SIZES[dIdx]); dest.val[sIdx] = total - dest.val[dIdx]; dest.val[restIdx] = source.val[restIdx]; dest.calcHash(); } int found = 0; void update(int val, int k){ if (steps[val] == -1){ steps[val] = k; ++found; } } int main(){ int a, b, c; memset(steps, -1, MAX_SIZE * sizeof(int)); scanf("%d %d %d", &SIZES[0], &SIZES[1], &SIZES[2]); scanf("%d %d %d", &a, &b, &c); // std::unordered_set<State, HashStruct> visited; std::set<State> visited; std::queue<Krok> queue; State start(a,b,c); queue.push(Krok(start,0)); visited.insert(start); State stany[6]; while (!queue.empty() && found < SIZES[2] + 1){ Krok k = queue.front(); queue.pop(); update(k.first.val[0], k.second); update(k.first.val[1], k.second); update(k.first.val[2], k.second); // printf("STAN %d %d %d\n",k.first.val[0],k.first.val[1],k.first.val[2]); getStan(k.first, stany[0], 0, 1, 2); getStan(k.first, stany[1], 0, 2, 1); getStan(k.first, stany[2], 1, 0, 2); getStan(k.first, stany[3], 1, 2, 0); getStan(k.first, stany[4], 2, 0, 1); getStan(k.first, stany[5], 2, 1, 0); for(int i = 0; i < 6; ++i){ // printf("=== %d %d %d\n",stany[i].val[0],stany[i].val[1],stany[i].val[2]); if (visited.find(stany[i]) == visited.end()){ // printf(">>> %d %d %d\n",stany[i].val[0],stany[i].val[1],stany[i].val[2]); visited.insert(stany[i]); queue.push(Krok(stany[i],k.second + 1)); } } } for(int i = 0; i < SIZES[2] + 1; ++i) printf("%d ", steps[i]); printf("\n"); return 0; } |