#include <cstdio> #include <list> struct ExperimentStep { int indexOfPhialA; int indexOfPhialB; }; struct ContentOfPhial { int index; int mass; }; class Phial { public: static int massOfSediment; static int reactiveSubstances[2]; static int numberOfReactions; static int numberOfReceivedReactions; static int numberOfPhials; static Phial** listOfPhials; std::list<ContentOfPhial> allContentOfPhial; int maxSubstancesIndex; int minSubstancesIndex; int indexOfPhial; Phial(ContentOfPhial c); ~Phial(); Phial& operator+(Phial& p); static void readNextReaction(); }; // initialize static members int Phial::massOfSediment = 0; int Phial::reactiveSubstances[2] = {-1, -1}; int Phial::numberOfReactions = 0; int Phial::numberOfReceivedReactions = 0; int Phial::numberOfPhials = 0; Phial** Phial::listOfPhials = NULL; Phial::Phial(ContentOfPhial c) { indexOfPhial = c.index - 1; maxSubstancesIndex = minSubstancesIndex = c.index; allContentOfPhial.push_back(c); } Phial::~Phial() { } Phial& Phial::operator+(Phial& p) { std::list<ContentOfPhial>::iterator itA = this->allContentOfPhial.end(); std::list<ContentOfPhial>::iterator itB = p.allContentOfPhial.end(); // check if used phials have substances which react each other if (this->minSubstancesIndex <= reactiveSubstances[0]) { for(std::list<ContentOfPhial>::iterator it0 = this->allContentOfPhial.begin(); it0 != this->allContentOfPhial.end(); ++it0) { if (it0->index == reactiveSubstances[0]) { itA = it0; if (p.maxSubstancesIndex >= reactiveSubstances[1]) { for(std::list<ContentOfPhial>::iterator it1 = p.allContentOfPhial.begin(); it1 != p.allContentOfPhial.end(); ++it1) { if (it1->index == reactiveSubstances[1]) { itB = it1; break; } } } break; } } } else if (this->maxSubstancesIndex >= reactiveSubstances[1]) { for(std::list<ContentOfPhial>::iterator it0 = this->allContentOfPhial.begin(); it0 != this->allContentOfPhial.end(); ++it0) { if (it0->index == reactiveSubstances[1]) { itA = it0; if (p.minSubstancesIndex <= reactiveSubstances[0]) { for(std::list<ContentOfPhial>::iterator it1 = p.allContentOfPhial.begin(); it1 != p.allContentOfPhial.end(); ++it1) { if (it1->index == reactiveSubstances[0]) { itB = it1; break; } } } break; } } } // if used phials have substances which react each other // calculate sediment which will be created if (itA != this->allContentOfPhial.end() && itB != p.allContentOfPhial.end()) { int massUsedToReaction = 0; if (itA->mass > itB->mass) { massUsedToReaction = itB->mass; p.allContentOfPhial.erase(itB); itA->mass -= massUsedToReaction; } else { massUsedToReaction = itA->mass; this->allContentOfPhial.erase(itA); itB->mass -= massUsedToReaction; } massOfSediment += (2 * massUsedToReaction); // if exists read next reaction if (numberOfReceivedReactions < numberOfReactions) { readNextReaction(); } } // pour the contents of the second phial into the first phial for (std::list<ContentOfPhial>::iterator it = p.allContentOfPhial.begin(); it != p.allContentOfPhial.end(); ++it) { this->allContentOfPhial.push_back(*it); } if (this->minSubstancesIndex > p.minSubstancesIndex) this->minSubstancesIndex = p.minSubstancesIndex; if (this->maxSubstancesIndex < p.maxSubstancesIndex) this->maxSubstancesIndex = p.maxSubstancesIndex; // clear empty phial int indexOfEmptyPhial = p.indexOfPhial; if (indexOfEmptyPhial < numberOfPhials && listOfPhials[indexOfEmptyPhial] != NULL) { delete listOfPhials[indexOfEmptyPhial]; listOfPhials[indexOfEmptyPhial] = NULL; } return *this; } void Phial::readNextReaction() { int substanceA, substanceB; scanf("%d %d", &substanceA, &substanceB); if (substanceA > substanceB) { reactiveSubstances[0] = substanceB; reactiveSubstances[1] = substanceA; } else { reactiveSubstances[0] = substanceA; reactiveSubstances[1] = substanceB; } numberOfReceivedReactions++; } int main(int argc, char* argv[]) { // read number of phials, steps and reactions int numberOfSteps = 0; scanf("%d %d %d", &Phial::numberOfPhials, &numberOfSteps, &Phial::numberOfReactions); // read masses of phials Phial::listOfPhials = new Phial*[Phial::numberOfPhials]; int x = 0; for (int i = 0; i < Phial::numberOfPhials; ++i) { scanf("%d", &x); Phial::listOfPhials[i] = new Phial({(i + 1), x}); } // read steps of experiment ExperimentStep* experimentSteps = new ExperimentStep[numberOfSteps]; for (int i = 0; i < numberOfSteps; ++i) { scanf("%d %d", &experimentSteps[i].indexOfPhialA, &experimentSteps[i].indexOfPhialB); } // read first reaction Phial::readNextReaction(); // do all steps for (int i = 0; i < numberOfSteps; ++i) { *Phial::listOfPhials[experimentSteps[i].indexOfPhialB - 1] = *Phial::listOfPhials[experimentSteps[i].indexOfPhialB - 1] + *Phial::listOfPhials[experimentSteps[i].indexOfPhialA - 1]; } // display value of mass of sediment printf("%d\n", Phial::massOfSediment); // clean up delete Phial::listOfPhials; delete experimentSteps; 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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #include <cstdio> #include <list> struct ExperimentStep { int indexOfPhialA; int indexOfPhialB; }; struct ContentOfPhial { int index; int mass; }; class Phial { public: static int massOfSediment; static int reactiveSubstances[2]; static int numberOfReactions; static int numberOfReceivedReactions; static int numberOfPhials; static Phial** listOfPhials; std::list<ContentOfPhial> allContentOfPhial; int maxSubstancesIndex; int minSubstancesIndex; int indexOfPhial; Phial(ContentOfPhial c); ~Phial(); Phial& operator+(Phial& p); static void readNextReaction(); }; // initialize static members int Phial::massOfSediment = 0; int Phial::reactiveSubstances[2] = {-1, -1}; int Phial::numberOfReactions = 0; int Phial::numberOfReceivedReactions = 0; int Phial::numberOfPhials = 0; Phial** Phial::listOfPhials = NULL; Phial::Phial(ContentOfPhial c) { indexOfPhial = c.index - 1; maxSubstancesIndex = minSubstancesIndex = c.index; allContentOfPhial.push_back(c); } Phial::~Phial() { } Phial& Phial::operator+(Phial& p) { std::list<ContentOfPhial>::iterator itA = this->allContentOfPhial.end(); std::list<ContentOfPhial>::iterator itB = p.allContentOfPhial.end(); // check if used phials have substances which react each other if (this->minSubstancesIndex <= reactiveSubstances[0]) { for(std::list<ContentOfPhial>::iterator it0 = this->allContentOfPhial.begin(); it0 != this->allContentOfPhial.end(); ++it0) { if (it0->index == reactiveSubstances[0]) { itA = it0; if (p.maxSubstancesIndex >= reactiveSubstances[1]) { for(std::list<ContentOfPhial>::iterator it1 = p.allContentOfPhial.begin(); it1 != p.allContentOfPhial.end(); ++it1) { if (it1->index == reactiveSubstances[1]) { itB = it1; break; } } } break; } } } else if (this->maxSubstancesIndex >= reactiveSubstances[1]) { for(std::list<ContentOfPhial>::iterator it0 = this->allContentOfPhial.begin(); it0 != this->allContentOfPhial.end(); ++it0) { if (it0->index == reactiveSubstances[1]) { itA = it0; if (p.minSubstancesIndex <= reactiveSubstances[0]) { for(std::list<ContentOfPhial>::iterator it1 = p.allContentOfPhial.begin(); it1 != p.allContentOfPhial.end(); ++it1) { if (it1->index == reactiveSubstances[0]) { itB = it1; break; } } } break; } } } // if used phials have substances which react each other // calculate sediment which will be created if (itA != this->allContentOfPhial.end() && itB != p.allContentOfPhial.end()) { int massUsedToReaction = 0; if (itA->mass > itB->mass) { massUsedToReaction = itB->mass; p.allContentOfPhial.erase(itB); itA->mass -= massUsedToReaction; } else { massUsedToReaction = itA->mass; this->allContentOfPhial.erase(itA); itB->mass -= massUsedToReaction; } massOfSediment += (2 * massUsedToReaction); // if exists read next reaction if (numberOfReceivedReactions < numberOfReactions) { readNextReaction(); } } // pour the contents of the second phial into the first phial for (std::list<ContentOfPhial>::iterator it = p.allContentOfPhial.begin(); it != p.allContentOfPhial.end(); ++it) { this->allContentOfPhial.push_back(*it); } if (this->minSubstancesIndex > p.minSubstancesIndex) this->minSubstancesIndex = p.minSubstancesIndex; if (this->maxSubstancesIndex < p.maxSubstancesIndex) this->maxSubstancesIndex = p.maxSubstancesIndex; // clear empty phial int indexOfEmptyPhial = p.indexOfPhial; if (indexOfEmptyPhial < numberOfPhials && listOfPhials[indexOfEmptyPhial] != NULL) { delete listOfPhials[indexOfEmptyPhial]; listOfPhials[indexOfEmptyPhial] = NULL; } return *this; } void Phial::readNextReaction() { int substanceA, substanceB; scanf("%d %d", &substanceA, &substanceB); if (substanceA > substanceB) { reactiveSubstances[0] = substanceB; reactiveSubstances[1] = substanceA; } else { reactiveSubstances[0] = substanceA; reactiveSubstances[1] = substanceB; } numberOfReceivedReactions++; } int main(int argc, char* argv[]) { // read number of phials, steps and reactions int numberOfSteps = 0; scanf("%d %d %d", &Phial::numberOfPhials, &numberOfSteps, &Phial::numberOfReactions); // read masses of phials Phial::listOfPhials = new Phial*[Phial::numberOfPhials]; int x = 0; for (int i = 0; i < Phial::numberOfPhials; ++i) { scanf("%d", &x); Phial::listOfPhials[i] = new Phial({(i + 1), x}); } // read steps of experiment ExperimentStep* experimentSteps = new ExperimentStep[numberOfSteps]; for (int i = 0; i < numberOfSteps; ++i) { scanf("%d %d", &experimentSteps[i].indexOfPhialA, &experimentSteps[i].indexOfPhialB); } // read first reaction Phial::readNextReaction(); // do all steps for (int i = 0; i < numberOfSteps; ++i) { *Phial::listOfPhials[experimentSteps[i].indexOfPhialB - 1] = *Phial::listOfPhials[experimentSteps[i].indexOfPhialB - 1] + *Phial::listOfPhials[experimentSteps[i].indexOfPhialA - 1]; } // display value of mass of sediment printf("%d\n", Phial::massOfSediment); // clean up delete Phial::listOfPhials; delete experimentSteps; return 0; } |