#include <cstdio> #include <vector> #include <queue> #include <utility> static const unsigned int MAX_MONSTERS_COUNT = 100 * 1000; static const unsigned int MAX_HP = 100 * 1000; struct Monster { int id; int hpDrain, hpReward; inline int hpDelta() const { return hpReward - hpDrain; } struct OutcomeCompare { inline bool operator()(const Monster & m1, const Monster & m2) const { return m1.hpDelta() < m2.hpDelta(); } }; struct MinHPCompare { inline bool operator()(const Monster & m1, const Monster & m2) const { return m1.hpDrain > m2.hpDrain; } }; }; typedef std::priority_queue<Monster, std::vector<Monster>, Monster::OutcomeCompare> deltaQueue_t; typedef std::priority_queue<Monster, std::vector<Monster>, Monster::MinHPCompare> drainQueue_t; bool solve( long long hp, drainQueue_t & monstersTooHardToKill, std::vector<int> & killingOrder ) { deltaQueue_t candidatesForMove; int monsterCount = monstersTooHardToKill.size(); for (int i = 0; i < monsterCount; i++) { while (!monstersTooHardToKill.empty() && hp - monstersTooHardToKill.top().hpDrain > 0) { candidatesForMove.push(monstersTooHardToKill.top()); monstersTooHardToKill.pop(); } if (candidatesForMove.empty()) return false; killingOrder.push_back(candidatesForMove.top().id); hp += candidatesForMove.top().hpDelta(); candidatesForMove.pop(); } return true; } int main() { int monsterCount; long long hp, endHp; scanf("%d %lld", &monsterCount, &hp); endHp = hp; drainQueue_t positiveMonsters, negativeMonsters; std::vector<int> positiveKillingOrder, negativeKillingOrder; for (int i = 0; i < monsterCount; i++) { Monster m; m.id = i + 1; scanf("%d %d", &m.hpDrain, &m.hpReward); endHp += m.hpDelta(); if (m.hpDelta() >= 0) positiveMonsters.push(m); else { std::swap(m.hpDrain, m.hpReward); negativeMonsters.push(m); } } if (endHp > 0 && solve(hp, positiveMonsters, positiveKillingOrder) && solve(endHp, negativeMonsters, negativeKillingOrder)) { puts("TAK"); for (auto it = positiveKillingOrder.begin(); it != positiveKillingOrder.end(); it++) printf("%d ", *it); for (auto it = negativeKillingOrder.rbegin(); it != negativeKillingOrder.rend(); it++) printf("%d ", *it); puts(""); } else puts("NIE"); 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 | #include <cstdio> #include <vector> #include <queue> #include <utility> static const unsigned int MAX_MONSTERS_COUNT = 100 * 1000; static const unsigned int MAX_HP = 100 * 1000; struct Monster { int id; int hpDrain, hpReward; inline int hpDelta() const { return hpReward - hpDrain; } struct OutcomeCompare { inline bool operator()(const Monster & m1, const Monster & m2) const { return m1.hpDelta() < m2.hpDelta(); } }; struct MinHPCompare { inline bool operator()(const Monster & m1, const Monster & m2) const { return m1.hpDrain > m2.hpDrain; } }; }; typedef std::priority_queue<Monster, std::vector<Monster>, Monster::OutcomeCompare> deltaQueue_t; typedef std::priority_queue<Monster, std::vector<Monster>, Monster::MinHPCompare> drainQueue_t; bool solve( long long hp, drainQueue_t & monstersTooHardToKill, std::vector<int> & killingOrder ) { deltaQueue_t candidatesForMove; int monsterCount = monstersTooHardToKill.size(); for (int i = 0; i < monsterCount; i++) { while (!monstersTooHardToKill.empty() && hp - monstersTooHardToKill.top().hpDrain > 0) { candidatesForMove.push(monstersTooHardToKill.top()); monstersTooHardToKill.pop(); } if (candidatesForMove.empty()) return false; killingOrder.push_back(candidatesForMove.top().id); hp += candidatesForMove.top().hpDelta(); candidatesForMove.pop(); } return true; } int main() { int monsterCount; long long hp, endHp; scanf("%d %lld", &monsterCount, &hp); endHp = hp; drainQueue_t positiveMonsters, negativeMonsters; std::vector<int> positiveKillingOrder, negativeKillingOrder; for (int i = 0; i < monsterCount; i++) { Monster m; m.id = i + 1; scanf("%d %d", &m.hpDrain, &m.hpReward); endHp += m.hpDelta(); if (m.hpDelta() >= 0) positiveMonsters.push(m); else { std::swap(m.hpDrain, m.hpReward); negativeMonsters.push(m); } } if (endHp > 0 && solve(hp, positiveMonsters, positiveKillingOrder) && solve(endHp, negativeMonsters, negativeKillingOrder)) { puts("TAK"); for (auto it = positiveKillingOrder.begin(); it != positiveKillingOrder.end(); it++) printf("%d ", *it); for (auto it = negativeKillingOrder.rbegin(); it != negativeKillingOrder.rend(); it++) printf("%d ", *it); puts(""); } else puts("NIE"); return 0; } |