// Animal Transport by Herbert Meiler #include #include #include #include const int AnimalTypes = 4; int MapAnimalType(char c) { int type = -1; switch (c) { case 'D': type = 0; break; case 'C': type = 1; break; case 'M': type = 2; break; case 'E': type = 3; break; } return type; } int PrevAnimalType(int animalType) { return (animalType > 0) ? (animalType - 1) : (AnimalTypes - 1); } int NextAnimalType(int animalType) { return (animalType + 1) % AnimalTypes; } struct Packet { int animalType; int srcZoo; int dstZoo; }; struct Solver { Solver(const std::vector& packets, int zooCount) : packets(packets), invalidPath(zooCount + 1) { } int Solve(int animalCount) const { std::vector route; const int result = Solve(route, animalCount); return (invalidPath == result) ? -1 : result; } private: int Solve(std::vector& route, int animalCount, int startIndex = 0) const { if (animalCount == 0) { return route.back().dstZoo; } int result = invalidPath; for (int index = startIndex; index != packets.size(); ++index) { const auto& packet = packets[index]; if (CanAdd(route, packet)) { route.push_back(packet); const int newResult = Solve(route, animalCount - 1, index + 1); result = std::min(result, newResult); route.pop_back(); } } return result; } bool CanAdd(const std::vector& route, const Packet& packet) const { bool ok = true; const auto prev = PrevAnimalType(packet.animalType); const auto next = NextAnimalType(packet.animalType); for (auto it = route.rbegin(); it != route.rend(); ++it) { if (packet.srcZoo >= it->dstZoo) { break; } if ((it->animalType == prev) || (it->animalType == next)) { ok = false; break; } } return ok; } const std::vector& packets; const int invalidPath; }; int main() { std::istream& is = std::cin; std::ostream& os = std::cout; int testCases; is >> testCases; while (testCases--) { int zooCount; is >> zooCount; int animalCount; is >> animalCount; std::vector packets(animalCount); for (int i = 0; i != animalCount; ++i) { char animalType; is >> animalType; packets[i].animalType = MapAnimalType(animalType); } for (int i = 0; i != animalCount; ++i) { int srcZoo; is >> srcZoo; packets[i].srcZoo = srcZoo; } for (int i = 0; i != animalCount; ++i) { int dstZoo; is >> dstZoo; packets[i].dstZoo = dstZoo; } std::sort(packets.begin(), packets.end(), [](const Packet& left, const Packet& right) -> bool { if (left.dstZoo < right.dstZoo) { return true; } if (left.dstZoo > right.dstZoo) { return false; } if (left.srcZoo < right.srcZoo) { return true; } if (left.srcZoo > right.srcZoo) { return false; } return (left.animalType < right.animalType); }); Solver solver(packets, zooCount); int countAnimals; for (countAnimals = 1; countAnimals <= animalCount; ++countAnimals) { const int result = solver.Solve(countAnimals); if (countAnimals > 1) { os << " "; } os << result; if (result == -1) { ++countAnimals; break; } } for (; countAnimals <= animalCount; ++countAnimals) { if (countAnimals > 1) { os << " "; } os << "-1"; } os << std::endl; } return 0; }