// A-5_BUT_Butelki.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;
//equals and hashcode from https://thispointer.com/how-to-use-unordered_set-with-user-defined-classes-tutorial-example/
class State {
public:
int bottle[3];
const bool operator==(const State& otherPoint) const
{
if (this->bottle[0] == otherPoint.bottle[0]
&& this->bottle[1] == otherPoint.bottle[1]
&& this->bottle[2] == otherPoint.bottle[2])
return true;
else return false;
}
};
namespace std
{
template<> struct hash<State>
{
size_t operator()(const State& obj) const
{
size_t hashZero = std::hash<int>()(obj.bottle[0]);
size_t hashOne = std::hash<int>()(obj.bottle[1]) << 1;
size_t hashTwo = std::hash<int>()(obj.bottle[2]) << 2; //TODO: i wonder, if this is bit shift and if it doesnt lose data here
return hashZero ^ hashOne ^ hashTwo;
}
};
}
int main()
{
State cappacity;
cin >> cappacity.bottle[0] >> cappacity.bottle[1] >> cappacity.bottle[2];
State start;
cin >> start.bottle[0] >> start.bottle[1] >> start.bottle[2];
int n = cappacity.bottle[2]+1;
long long* minNumberOfMoves = new long long[n];
fill_n(minNumberOfMoves, n, -1);
int stillToBeFound = n;
unordered_set<State> reachedStates;
vector<State>* statesToBeEvaluated = new vector<State>;
vector<State>* visibleStates = new vector<State>;
visibleStates->push_back(start);
long long moveNo = 0;
reachedStates.insert(start);
minNumberOfMoves[start.bottle[0]] = moveNo;
minNumberOfMoves[start.bottle[1]] = moveNo;
minNumberOfMoves[start.bottle[2]] = moveNo;
stillToBeFound -= 3;
while (!visibleStates->empty()) {
vector<State>* swapTemp;
swapTemp = statesToBeEvaluated;
statesToBeEvaluated = visibleStates;
visibleStates = swapTemp;
visibleStates->clear();
moveNo++;
while (!statesToBeEvaluated->empty()) {
State current = statesToBeEvaluated->back();
statesToBeEvaluated->pop_back();
//Move whatever is possible from j to i
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (i != j) {
int liquidInIandJ = current.bottle[i] + current.bottle[j];
int indexOfNotUsedBottle = 0 + 1 + 2 - i - j;
State possiblyNewState;
possiblyNewState.bottle[i]=min(cappacity.bottle[i], liquidInIandJ);
possiblyNewState.bottle[j] = liquidInIandJ - possiblyNewState.bottle[i];
possiblyNewState.bottle[indexOfNotUsedBottle]= current.bottle[indexOfNotUsedBottle];
if (reachedStates.find(possiblyNewState)==reachedStates.end()) {
//not seen before
reachedStates.insert(possiblyNewState);
if (minNumberOfMoves[possiblyNewState.bottle[i]] == -1) {
minNumberOfMoves[possiblyNewState.bottle[i]] = moveNo;
stillToBeFound--;
}
if (minNumberOfMoves[possiblyNewState.bottle[j]] == -1) {
minNumberOfMoves[possiblyNewState.bottle[j]] = moveNo;
stillToBeFound--;
}
visibleStates->push_back(possiblyNewState);
}
}
}
}
}//end of "while (!statesToBeEvaluated->empty())"
if (stillToBeFound == 0) break;
}
for (int i = 0; i < n; ++i) cout << minNumberOfMoves[i] << " ";
}
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu
// Tips for Getting Started:
// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
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 | // A-5_BUT_Butelki.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include <iostream> #include <unordered_set> #include <vector> using namespace std; //equals and hashcode from https://thispointer.com/how-to-use-unordered_set-with-user-defined-classes-tutorial-example/ class State { public: int bottle[3]; const bool operator==(const State& otherPoint) const { if (this->bottle[0] == otherPoint.bottle[0] && this->bottle[1] == otherPoint.bottle[1] && this->bottle[2] == otherPoint.bottle[2]) return true; else return false; } }; namespace std { template<> struct hash<State> { size_t operator()(const State& obj) const { size_t hashZero = std::hash<int>()(obj.bottle[0]); size_t hashOne = std::hash<int>()(obj.bottle[1]) << 1; size_t hashTwo = std::hash<int>()(obj.bottle[2]) << 2; //TODO: i wonder, if this is bit shift and if it doesnt lose data here return hashZero ^ hashOne ^ hashTwo; } }; } int main() { State cappacity; cin >> cappacity.bottle[0] >> cappacity.bottle[1] >> cappacity.bottle[2]; State start; cin >> start.bottle[0] >> start.bottle[1] >> start.bottle[2]; int n = cappacity.bottle[2]+1; long long* minNumberOfMoves = new long long[n]; fill_n(minNumberOfMoves, n, -1); int stillToBeFound = n; unordered_set<State> reachedStates; vector<State>* statesToBeEvaluated = new vector<State>; vector<State>* visibleStates = new vector<State>; visibleStates->push_back(start); long long moveNo = 0; reachedStates.insert(start); minNumberOfMoves[start.bottle[0]] = moveNo; minNumberOfMoves[start.bottle[1]] = moveNo; minNumberOfMoves[start.bottle[2]] = moveNo; stillToBeFound -= 3; while (!visibleStates->empty()) { vector<State>* swapTemp; swapTemp = statesToBeEvaluated; statesToBeEvaluated = visibleStates; visibleStates = swapTemp; visibleStates->clear(); moveNo++; while (!statesToBeEvaluated->empty()) { State current = statesToBeEvaluated->back(); statesToBeEvaluated->pop_back(); //Move whatever is possible from j to i for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { if (i != j) { int liquidInIandJ = current.bottle[i] + current.bottle[j]; int indexOfNotUsedBottle = 0 + 1 + 2 - i - j; State possiblyNewState; possiblyNewState.bottle[i]=min(cappacity.bottle[i], liquidInIandJ); possiblyNewState.bottle[j] = liquidInIandJ - possiblyNewState.bottle[i]; possiblyNewState.bottle[indexOfNotUsedBottle]= current.bottle[indexOfNotUsedBottle]; if (reachedStates.find(possiblyNewState)==reachedStates.end()) { //not seen before reachedStates.insert(possiblyNewState); if (minNumberOfMoves[possiblyNewState.bottle[i]] == -1) { minNumberOfMoves[possiblyNewState.bottle[i]] = moveNo; stillToBeFound--; } if (minNumberOfMoves[possiblyNewState.bottle[j]] == -1) { minNumberOfMoves[possiblyNewState.bottle[j]] = moveNo; stillToBeFound--; } visibleStates->push_back(possiblyNewState); } } } } }//end of "while (!statesToBeEvaluated->empty())" if (stillToBeFound == 0) break; } for (int i = 0; i < n; ++i) cout << minNumberOfMoves[i] << " "; } // Run program: Ctrl + F5 or Debug > Start Without Debugging menu // Debug program: F5 or Debug > Start Debugging menu // Tips for Getting Started: // 1. Use the Solution Explorer window to add/manage files // 2. Use the Team Explorer window to connect to source control // 3. Use the Output window to see build output and other messages // 4. Use the Error List window to view errors // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file |
English