#include <iostream>
#include <list>
using namespace std;
class Monster {
public: // dla wygody wszystko publiczne
int numer;
int dmg;
int heal;
int dif; // roznica heal - dmg, dla szybkosci liczona tylko raz i przechowana
// przy ustalaniu kolejnosci ubijania potworow bedzie potrzebna mozliwosc
// porownania damagu jaki robia, do tego przyda sie operator porownania,
// uzywany w taki sposob: if (monster1 < monster2) ...
bool operator<(Monster m) {
return (dmg < m.dmg);
}
};
/*
Na poczatku gry intuicyjnie wydaje sie rozsadnym poexpic poprzez wybieranie
takich potworow, ktore 1. sa slabe i nie zabija bohatera oraz 2. przywracaja
wiecej zycia niz zabieraja. Gdy bohater przypakuje moze sie brac za potwory
grozniejsze, starajac sie jak najdluzej zachowac jak najwiecej zycia, a wiec
najpierw za te po ubiciu ktorych odzyska jak najwieksza czesc straconego zycia.
*/
bool porownaj(const Monster& m1, const Monster& m2);
void wypisz(list<int> * kolejnosc_potworow);
bool rozwiaz(list<Monster> * potwory_do_expienia,
list<Monster> * potwory_neutralne,
list<Monster> * potwory_grozne,
list<int> * kolejnosc_potworow,
int z);
int main()
{
// struktury danych
int n, z, di, ai, dh;
list<Monster> * potwory_do_expienia = new list<Monster>();
list<Monster> * potwory_neutralne = new list<Monster>();
list<Monster> * potwory_grozne = new list<Monster>();
list<int> * kolejnosc_potworow = new list<int>;
// wczytaj dane
cin >> n;
cin >> z;
for (int i=1 ; i<=n ; i++) {
cin >> di, cin >> ai;
dh = ai - di;
if (dh > 0) {
potwory_do_expienia->push_back({i, di, ai, dh});
} else if (dh == 0) {
potwory_neutralne->push_back({i, di, ai, dh});
} else {
potwory_grozne->push_back({i, di, ai, dh});
}
}
// posortuj potwory od najslabszego do najsilniejszego
// podzial potworow na mniejsze zbiory przyspiesza nieco ten etap
// potwory do expienia sortujemy po damagu, poslugujac sie operatorem <
potwory_do_expienia->sort();
// potwory grozne sortujemy po roznicy heal - dmg, korzystajac z pomocniczej funkcji
potwory_grozne->sort(); // szybki
potwory_grozne->reverse(); // fix
potwory_grozne->sort(porownaj);
// potworow neutralnych nie trzeba sortowac, kolejnosc ich ubijania jest nieistotna
if (rozwiaz(potwory_do_expienia,
potwory_neutralne,
potwory_grozne,
kolejnosc_potworow,
z) == true) {
// jesli udalo sie przezyc
wypisz(kolejnosc_potworow);
} else {
// jesli bohater polegl
cout << "NIE" << endl;
}
return 0;
}
// funkcja przyjmuje wskazniki do list, co oznacza ze sa one modyfikowalne
bool rozwiaz(list<Monster> * potwory_do_expienia,
list<Monster> * potwory_neutralne,
list<Monster> * potwory_grozne,
list<int> * kolejnosc_potworow,
int z) {
// czas poexpic - co nie zabije to wzmocni
for (list<Monster>::iterator it=potwory_do_expienia->begin() ; it != potwory_do_expienia->end() ; ++it) {
if (it->dmg >= z) {
return false;
} else {
z += it->dif;
kolejnosc_potworow->push_back(it->numer);
}
}
// powybijac potwory neutralne
for (list<Monster>::iterator it=potwory_neutralne->begin() ; it != potwory_neutralne->end() ; ++it) {
if (it->dmg >= z) {
return false;
} else {
kolejnosc_potworow->push_back(it->numer);
}
}
// na koniec potwory ktore nie przywracaja calego zabranego zycia
for (list<Monster>::iterator it=potwory_grozne->begin() ; it != potwory_grozne->end() ; ++it) {
if (it->dmg >= z) {
return false;
} else {
z += it->dif;
kolejnosc_potworow->push_back(it->numer);
}
}
return true;
}
void wypisz(list<int> * kolejnosc_potworow) {
cout << "TAK" << endl;
list<int>::iterator ostatni = kolejnosc_potworow->end();
ostatni--;
for (list<int>::iterator it=kolejnosc_potworow->begin() ; it != kolejnosc_potworow->end() ; ++it) {
cout << *it;
if (it != ostatni)
cout << " ";
}
cout << endl;
}
bool porownaj(const Monster& m1, const Monster& m2) {
return (m1.dif < m2.dif);
}
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 | #include <iostream> #include <list> using namespace std; class Monster { public: // dla wygody wszystko publiczne int numer; int dmg; int heal; int dif; // roznica heal - dmg, dla szybkosci liczona tylko raz i przechowana // przy ustalaniu kolejnosci ubijania potworow bedzie potrzebna mozliwosc // porownania damagu jaki robia, do tego przyda sie operator porownania, // uzywany w taki sposob: if (monster1 < monster2) ... bool operator<(Monster m) { return (dmg < m.dmg); } }; /* Na poczatku gry intuicyjnie wydaje sie rozsadnym poexpic poprzez wybieranie takich potworow, ktore 1. sa slabe i nie zabija bohatera oraz 2. przywracaja wiecej zycia niz zabieraja. Gdy bohater przypakuje moze sie brac za potwory grozniejsze, starajac sie jak najdluzej zachowac jak najwiecej zycia, a wiec najpierw za te po ubiciu ktorych odzyska jak najwieksza czesc straconego zycia. */ bool porownaj(const Monster& m1, const Monster& m2); void wypisz(list<int> * kolejnosc_potworow); bool rozwiaz(list<Monster> * potwory_do_expienia, list<Monster> * potwory_neutralne, list<Monster> * potwory_grozne, list<int> * kolejnosc_potworow, int z); int main() { // struktury danych int n, z, di, ai, dh; list<Monster> * potwory_do_expienia = new list<Monster>(); list<Monster> * potwory_neutralne = new list<Monster>(); list<Monster> * potwory_grozne = new list<Monster>(); list<int> * kolejnosc_potworow = new list<int>; // wczytaj dane cin >> n; cin >> z; for (int i=1 ; i<=n ; i++) { cin >> di, cin >> ai; dh = ai - di; if (dh > 0) { potwory_do_expienia->push_back({i, di, ai, dh}); } else if (dh == 0) { potwory_neutralne->push_back({i, di, ai, dh}); } else { potwory_grozne->push_back({i, di, ai, dh}); } } // posortuj potwory od najslabszego do najsilniejszego // podzial potworow na mniejsze zbiory przyspiesza nieco ten etap // potwory do expienia sortujemy po damagu, poslugujac sie operatorem < potwory_do_expienia->sort(); // potwory grozne sortujemy po roznicy heal - dmg, korzystajac z pomocniczej funkcji potwory_grozne->sort(); // szybki potwory_grozne->reverse(); // fix potwory_grozne->sort(porownaj); // potworow neutralnych nie trzeba sortowac, kolejnosc ich ubijania jest nieistotna if (rozwiaz(potwory_do_expienia, potwory_neutralne, potwory_grozne, kolejnosc_potworow, z) == true) { // jesli udalo sie przezyc wypisz(kolejnosc_potworow); } else { // jesli bohater polegl cout << "NIE" << endl; } return 0; } // funkcja przyjmuje wskazniki do list, co oznacza ze sa one modyfikowalne bool rozwiaz(list<Monster> * potwory_do_expienia, list<Monster> * potwory_neutralne, list<Monster> * potwory_grozne, list<int> * kolejnosc_potworow, int z) { // czas poexpic - co nie zabije to wzmocni for (list<Monster>::iterator it=potwory_do_expienia->begin() ; it != potwory_do_expienia->end() ; ++it) { if (it->dmg >= z) { return false; } else { z += it->dif; kolejnosc_potworow->push_back(it->numer); } } // powybijac potwory neutralne for (list<Monster>::iterator it=potwory_neutralne->begin() ; it != potwory_neutralne->end() ; ++it) { if (it->dmg >= z) { return false; } else { kolejnosc_potworow->push_back(it->numer); } } // na koniec potwory ktore nie przywracaja calego zabranego zycia for (list<Monster>::iterator it=potwory_grozne->begin() ; it != potwory_grozne->end() ; ++it) { if (it->dmg >= z) { return false; } else { z += it->dif; kolejnosc_potworow->push_back(it->numer); } } return true; } void wypisz(list<int> * kolejnosc_potworow) { cout << "TAK" << endl; list<int>::iterator ostatni = kolejnosc_potworow->end(); ostatni--; for (list<int>::iterator it=kolejnosc_potworow->begin() ; it != kolejnosc_potworow->end() ; ++it) { cout << *it; if (it != ostatni) cout << " "; } cout << endl; } bool porownaj(const Monster& m1, const Monster& m2) { return (m1.dif < m2.dif); } |
English