#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; } |
English